params?
От: rameel https://github.com/rsdn/CodeJam
Дата: 01.05.07 14:35
Оценка:
Такое поведение нормально? Или это бага?
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>>
Re: params?
От: VladD2 Российская Империя www.nemerle.org
Дата: 01.05.07 15:25
Оценка: 7 (1)
Здравствуйте, 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>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: params?
От: rameel https://github.com/rsdn/CodeJam
Дата: 01.05.07 15:47
Оценка:
Здравствуйте, 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>>
Re[3]: params?
От: Блудов Павел Россия  
Дата: 02.05.07 02:09
Оценка:
Здравствуйте, rameel, Вы писали:

R>ЗЫ. Да, давно я Немерле не щупал

Рамиль, ты не стесняйся если что, приши предложения по укреплению дружбы между BLToolkit и Nemerle.
В данном конкретном случае нужно научить DbManager.SetSpCommand разгребать массивы из IDbDataParameters.
Dесь нужный код уже написан и живёт в DataAccessor.PrepareParameters(). Пишите сюда, прикрутим.
... << RSDN@Home 1.2.0 alpha rev. 642>>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.