Здравствуйте, nikov, Вы писали:
N>Здравствуйте, MatFiz, Вы писали:
MF>>Это стандарт такой тупой или компилер глючит?
N>Это такой стандарт. Смотреть разделы про метод, applicable in its normal form and applicable in its expanded form.
А есть ли какое-то логическое объяснение такому поведению?
Микрософт рекомендует не передавать null в случае коллекций, а пользоваться пустыми коллекциями.
И при этом сам же нарушает это правило и не где-нибудь, а прямо в реализации компилера C#.
Наверняка есть какие-то железные доводы, почему поведение настолько близких по внешнему виду кусков кода столь сильно отличается.
ИМХО, грабли те еще. Такое поведение не достойно промышленного стандарта.
How are YOU doin'?
Re[3]: Передаю явный null в params - баг или фича шарпа?
MF>А есть ли какое-то логическое объяснение такому поведению? MF>Микрософт рекомендует не передавать null в случае коллекций, а пользоваться пустыми коллекциями. MF>И при этом сам же нарушает это правило и не где-нибудь, а прямо в реализации компилера C#.
Можно пример нарушения?
Re[3]: Передаю явный null в params - баг или фича шарпа?
Здравствуйте, MatFiz, Вы писали:
N>>Это такой стандарт. Смотреть разделы про метод, applicable in its normal form and applicable in its expanded form.
MF>А есть ли какое-то логическое объяснение такому поведению?
Это сделано для удобства передачи массива через цепочку методов с params. И для возможности контроля за поведением (будет ли массив передаваться как есть, или будет становиться элементом нового массива) с помощью явного приведения типа.
class Program
{
static void Main()
{
Foo("a", "b");
}
static void Foo(params object[] x)
{
Bar(x); // передаем x как есть
Bar((object)x); // передаем x в качестве элемента нового массива
Bar(null); // передаем null как есть
Bar((object)null); // передаем null в качестве элемента нового массива
}
static void Bar(params object[] x) { }
}
Имхо, достаточно удобно и понятно.
Re[3]: Передаю явный null в params - баг или фича шарпа?
Здравствуйте, MatFiz, Вы писали:
MF>Микрософт рекомендует не передавать null в случае коллекций, а пользоваться пустыми коллекциями. MF>И при этом сам же нарушает это правило и не где-нибудь, а прямо в реализации компилера C#.
Не понятно, каким образом эта рекомендация относится к обсуждаемому правилу передачи аргументов в метод с params.
Re[3]: Передаю явный null в params - баг или фича шарпа?
Здравствуйте, MatFiz, Вы писали:
MF>Микрософт рекомендует не передавать null в случае коллекций, а пользоваться пустыми коллекциями.
Не передавать, а возвращать,насколько я знаю (Returning Empty Arrays) а это две большие разницы. Суть в том, что когда мне нужно куда-то передать массив, я имею право передать null (*) и "приёмник" обязан трактовать его так же, как и пустой массив. Наоборот: при возврате массива я обязан вернуть не пустую ссылку. Как показывает практика, это максимально удобный компромисс между удобством и производительностью.
(*) То, что "я имею право передать null" часто не верно для библиотек фреймворка, например из-за этого приходится пользоваться Type.EmptyTypes в таких методах, как Type.GetConstructor
Help will always be given at Hogwarts to those who ask for it.
Re[4]: Передаю явный null в params - баг или фича шарпа?
Здравствуйте, Andrbig, Вы писали:
MF>>А есть ли какое-то логическое объяснение такому поведению? MF>>Микрософт рекомендует не передавать null в случае коллекций, а пользоваться пустыми коллекциями. MF>>И при этом сам же нарушает это правило и не где-нибудь, а прямо в реализации компилера C#.
A>Можно пример нарушения?
Легко. Читай мой первый пост.
How are YOU doin'?
Re[4]: Передаю явный null в params - баг или фича шарпа?
Здравствуйте, nikov, Вы писали:
N>Имхо, достаточно удобно и понятно.
ИМХО, текущее поведение компилятора логически неоднородно:
int Foo(params object[] args)
{
return args.Count;
}
...
Assert.True(0, Foo());
Assert.True(1, Foo(null)); // Работает не так, как ожидается
Assert.True(2, Foo(null, null));
Assert.True(3, Foo(null, null, null));
object o = null;
// По-разному работают:
Assert.True(1, Foo(o));
Assert.True(1, Foo(null));
// Компилятору приходится подсказывать, явно указывая тип.
Assert.True(1, Foo(/*(object[])*/null));
Assert.True(1, Foo((object)null)); // Именно этот вариант я бы хотел вариантом по умолчанию