Передаю явный null в params - баг или фича шарпа?
От: MatFiz Россия  
Дата: 06.12.07 16:58
Оценка:
C# 3.0 (FW 3.5, хотя рантайм со второй версии вроде не менялся).

Код:
bool AllNull(params object[] values)
{
    return values.All(o => (o == null));  // Тут будет NullReferenceException: values == null (см. ниже)
}


вызываю:

object o = null;
AllNull(o);    // Все ОК

AllNull(null); // Получаю NRE


Это стандарт такой тупой или компилер глючит?
How are YOU doin'?
Re: Передаю явный null в params - баг или фича шарпа?
От: nikov США http://www.linkedin.com/in/nikov
Дата: 06.12.07 17:00
Оценка: 4 (1) +2
Здравствуйте, MatFiz, Вы писали:

MF>Это стандарт такой тупой или компилер глючит?


Это такой стандарт. Смотреть разделы про метод, applicable in its normal form and applicable in its expanded form.
Re: Передаю явный null в params - баг или фича шарпа?
От: nikov США http://www.linkedin.com/in/nikov
Дата: 06.12.07 17:05
Оценка: 1 (1) +1
Здравствуйте, MatFiz, Вы писали:

MF>C# 3.0 (FW 3.5, хотя рантайм со второй версии вроде не менялся).


Кстати, рантайм здесь совершенно не при чем. Этот вопрос разруливается компилятором.
Re[2]: Передаю явный null в params - баг или фича шарпа?
От: MatFiz Россия  
Дата: 06.12.07 19:18
Оценка: -3
Здравствуйте, 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 - баг или фича шарпа?
От: Andrbig  
Дата: 07.12.07 06:53
Оценка:
MF>А есть ли какое-то логическое объяснение такому поведению?
MF>Микрософт рекомендует не передавать null в случае коллекций, а пользоваться пустыми коллекциями.
MF>И при этом сам же нарушает это правило и не где-нибудь, а прямо в реализации компилера C#.

Можно пример нарушения?
Re[3]: Передаю явный null в params - баг или фича шарпа?
От: nikov США http://www.linkedin.com/in/nikov
Дата: 07.12.07 15:28
Оценка:
Здравствуйте, 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 - баг или фича шарпа?
От: nikov США http://www.linkedin.com/in/nikov
Дата: 07.12.07 15:30
Оценка:
Здравствуйте, MatFiz, Вы писали:

MF>Микрософт рекомендует не передавать null в случае коллекций, а пользоваться пустыми коллекциями.

MF>И при этом сам же нарушает это правило и не где-нибудь, а прямо в реализации компилера C#.

Не понятно, каким образом эта рекомендация относится к обсуждаемому правилу передачи аргументов в метод с params.
Re[3]: Передаю явный null в params - баг или фича шарпа?
От: _FRED_ Черногория
Дата: 07.12.07 15:47
Оценка:
Здравствуйте, 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 - баг или фича шарпа?
От: MatFiz Россия  
Дата: 08.12.07 14:11
Оценка:
Здравствуйте, Andrbig, Вы писали:

MF>>А есть ли какое-то логическое объяснение такому поведению?

MF>>Микрософт рекомендует не передавать null в случае коллекций, а пользоваться пустыми коллекциями.
MF>>И при этом сам же нарушает это правило и не где-нибудь, а прямо в реализации компилера C#.

A>Можно пример нарушения?


Легко. Читай мой первый пост.
How are YOU doin'?
Re[4]: Передаю явный null в params - баг или фича шарпа?
От: MatFiz Россия  
Дата: 08.12.07 14:42
Оценка:
Здравствуйте, 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));    // Именно этот вариант я бы хотел вариантом по умолчанию
How are YOU doin'?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.