Pergunta

Is this a bug or am I interpreting the '??'-operator wrong? Check out the get property below and the comments.

I'm using 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;
        }
    }

EDIT: Sorry to everybody who looked at the question when it was freshly asked, there where some errors in it that got to confuse everyone.

Thanks for all the great and fast feedback! I've now understood the error I made. Thanks!

Foi útil?

Solução

This line:

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

Is equivalent to:

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

Not to:

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

The version with ??, which you added later, is so unreadable that I won't analyze it. Let's get ? right first.

Outras dicas

If you must use ?? use it like

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

but a simple if is fine as well

When you use the syntax

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

if _myTypeList is null then you return a new MyType List of type List(). _myTypeList however still remains null. You do not initialize it.

Whereas in the second case, you actually initialize _myTypeList and then return it.

Version A:

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

Version B:

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

Version C:

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

A and C should behave the same. B should not -- it does not set _myTypeList to a new list, it only returns one. You can use the same syntax you use in version A to make it equivalent:

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

The ?? operator means: If the left hand operand is not null, the result of the operation is the left hand operand. Otherwise, the result of the operation is the right hand operand. I.e.:

foo = bar ?? frob

Then foo = bar if bar != null, otherwise, foo = frob.

The code you're demonstrating, doesn't use the ?? operator (coalesce operator). Instead, you're using the ternary operator.

Try

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

instead.

Check this out:

        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> () );
        }

The code above will output '_theList has been initialized'.

Your commented line:

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

Will never work as you expect, since you're not (lazy) initializing _myTypeList anywhere.
_myTypeList == null will always evaluate to true, since _mytypeList is never initialized, and thus, you'll always return a new List instance.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top