Такое поведение нормально? Или это бага?
Main() : void
{
def count = ParamsSample(GetValues());
WriteLine($"count: $count, expected: $(GetValues().Length)");
}
GetValues() : array[string]
{
array["1", "2", "3"];
}
ParamsSample(params values: array[object]) : int
{
values.Length;
}
Загвоздка в том, что такой код разворачивается в следующее, т.е. создается дополнительный массив для передачи в метод. Если же передавать значение с явным приведением в object GetValues():>array[object], то все нормально.
object[] values = new object[] { GetValues() };
int count = ParamsSample(values);
Console.WriteLine("count: " + Convert.ToString(count) + ", expected: " + Convert.ToString(GetValues().Length));
// печатает count: 1, expected: 3
ЗЫ. Заметил на примере BLToolkit
// C#. Полет нормальный
using (DbManager db = new DbManager())
db.SetSpCommand("Persons_Insert", db.CreateParameters(obj))
.ExecuteNonQuery();
// Немерле. Без выделенного полет обламывается :)
using (def db = DbManager())
_ = db.SetSpCommand("Persons_Insert", db.CreateParameters(obj):>array[object])
.ExecuteNonQuery();
... << RSDN@Home 1.2.0 alpha rev. 677>>
Здравствуйте, rameel, Вы писали:
R>Такое поведение нормально? Или это бага?
К сожалению, нормально (к сожалению, так как это отличается от поведения C#). Дело в том, что неявная ковариантность для массивов не поддерживается. По этому компилятор рассматривает массив object-ов как просто объект который нужно поместить первым аргументом фукнции с переменным числом аргументов.
В данной ситуации лучше объявить функцию как generic. Тогда все бует работать корректно.
Причем все что нужно сделать в этом примере — это заменит стоку:
ParamsSample(params values: array[object]) : int
на
ParamsSample[T](params values: array[T]) : int
... << RSDN@Home 1.2.0 alpha rev. 637>>
Здравствуйте, VladD2, Вы писали:
VD>К сожалению, нормально (к сожалению, так как это отличается от поведения C#). Дело в том, что неявная ковариантность для массивов не поддерживается. По этому компилятор рассматривает массив object-ов как просто объект который нужно поместить первым аргументом фукнции с переменным числом аргументов.
Буду иметь в виду.
VD>В данной ситуации лучше объявить функцию как generic. Тогда все бует работать корректно.
Это да, только был сбит столку, что к чему, когда такой код выдал мне сообщенице
using (def db = DbManager())
{
_ = db.SetSpCommand(GetSpName(person.GetType(), "Insert"), db.CreateParameters(person))
.ExecuteNonQuery();
}
Произошли ошибки во время выполнения многошаговой операции OLE DB. По возможности, проверьте значения всех состояний OLE DB. Работа не выполнена.
ЗЫ. Да, давно я Немерле не щупал
... << RSDN@Home 1.2.0 alpha rev. 677>>
Здравствуйте, rameel, Вы писали:
R>ЗЫ. Да, давно я Немерле не щупал
Рамиль, ты не стесняйся если что, приши предложения по укреплению дружбы между BLToolkit и Nemerle.
В данном конкретном случае нужно научить DbManager.SetSpCommand разгребать массивы из IDbDataParameters.
Dесь нужный код уже написан и живёт в DataAccessor.PrepareParameters(). Пишите
сюда, прикрутим.
... << RSDN@Home 1.2.0 alpha rev. 642>>