Странное поведение оператора «??» в C # 3.5 - PullRequest
0 голосов
/ 10 января 2012

Это ошибка или я неправильно интерпретирую оператор '??'?Проверьте свойство get ниже и комментарии.

Я использую C # .NET 3.5

    private List<MyType> _myTypeList;

    private List<MyType> MyTypeList
    {
        get
        {
            //The two code lines below should each behave as the three under, but they don't?
            //The ones uncommented are working, the commented result in my list always returning empty (newly created I suppose).

            //return _myTypeList ?? new List<MyType>();
            //return _myTypeList == null ? new List<MyType>() : _myTypeList;

            if (_myTypeList == null)
                _myTypeList = new List<MyType>();
            return _myTypeList;
        }
    }

РЕДАКТИРОВАТЬ: Извините всех, кто посмотрел на вопрос, когда он был недавно задан, тамгде некоторые ошибки, которые могут запутать всех.

Спасибо за все отличные и быстрые отзывы!Теперь я понял ошибку, которую я сделал. Спасибо!

Ответы [ 6 ]

6 голосов
/ 10 января 2012

Эта строка:

return _myTypeList == null ? new List<MyType>() : _myTypeList;

Эквивалентно:

    if (_myTypeList == null)
        return new List<MyType>();
    return _myTypeList;

Не:

    if (_myTypeList == null)
        _myTypeList = new List<MyType>();
    return _myTypeList;

Версия с ??, которую вы добавилипозже, это настолько нечитаемо, что я не буду анализировать это.Давайте сначала получим ?.

5 голосов
/ 10 января 2012

Если вы должны использовать ??, используйте его как

_myTypeList = _myTypeList ??  new List<MyType>();
return  _myTypeList;

, но просто, если все в порядке

3 голосов
/ 10 января 2012

При использовании синтаксиса

return _myTypeList == null ? new List<MyType>() : _myTypeList;

если _myTypeList равен нулю, вы возвращаете новый список MyType типа List (). _myTypeList однако все еще остается нулевым. Вы не инициализируете его.

Тогда как во втором случае вы фактически инициализируете _myTypeList, а затем возвращаете его.

1 голос
/ 10 января 2012

Оператор ?? означает: если левый операнд не равен null, результатом операции является левый операнд. В противном случае результатом операции является правый операнд. I.e.:

foo = bar ?? frob

Тогда foo = bar, если bar != null, в противном случае foo = frob.

1 голос
/ 10 января 2012

Версия A:

return _myTypeList ?? (_myTypeList = new List<MyType>()); 

Версия B:

return _myTypeList == null ? new List<MyType>() : _myTypeList; 

Версия C:

if (_myTypeList == null) 
    _myTypeList = new List<MyType>(); 
return _myTypeList; 

А и С должны вести себя одинаково. B не должен - он не устанавливает _myTypeList в новый список, он только возвращает один. Вы можете использовать тот же синтаксис, который вы используете в версии A, чтобы сделать его эквивалентным:

return _myTypeList == null ? _myTypeList = new List<MyType>() : _myTypeList; 
1 голос
/ 10 января 2012

Код, который вы демонстрируете, не использует ??оператор (оператор объединения).Вместо этого вы используете троичный оператор.

Попробуйте

return _myTypeList ?? ( _myTypeList = new List<MyType>() );

.

Проверьте это:

        static void Main( string[] args )
        {
            var x = GetList ();

            if( _theList == null )
            {
                Console.WriteLine ("_theList is null");
            }
            else
            {
                Console.WriteLine ("_theList has been initialized.");
            }
            Console.ReadLine ();
        }

        private static List<int> _theList;

        public static List<int> GetList()
        {
            return _theList ?? ( _theList = new List<int> () );
        }

Код вышевыведет '_theList был инициализирован'.

Ваша закомментированная строка:

//return _myTypeList == null ? new List<MyType>() : _myTypeList;

Никогда не будет работать так, как вы ожидаете, поскольку вы не (ленив) не инициализируете _myTypeList где-либо.
_myTypeList == nul l всегда будет иметь значение true, поскольку _mytypeList никогда не инициализируется, и, таким образом, вы всегда будете возвращать новый экземпляр List.

...