Assign to interface array initializator compiles but why?

前端 未结 4 963
星月不相逢
星月不相逢 2020-12-19 02:23

Today I was thinking it would be neat to make anonymous object which is type of some interface, and I have seen on SO that I am not only one.

Before I started checki

相关标签:
4条回答
  • 2020-12-19 02:46

    it would be neat to make anonymous object which is type of some interface,

    I know there is no way to do anonymous objects implement interface, but I have not seen complaint from VS about this code.

    The problem is, you're assuming that the following code creates a new instance of an anonymous type

    new Holder { someInterface = { Property = 1 } };
    

    { Property = 1 } does not create a new instance of an anonymous type - this is an object initializer.

    If you do replace your code with a proper instantiation of an anonymous type, then the compiler will complain that the instance cannot be implicitly converted to ISomeInterface, like you expected.

    new Holder { someInterface = new { Property = 1 } };
    
    0 讨论(0)
  • 2020-12-19 02:50

    You have to assign an instance to someInterface in Holder constractor; otherwise, it will be null.

    0 讨论(0)
  • 2020-12-19 02:58
    Holder holder = new Holder { someInterface = { Property = 1 } };//<--Note you missed new keyword
    

    Above line is equal to

    Holder temp = new Holder();
    temp.someInterface.Property = 1;
    Holder holder = temp;// <--Here someInterface is null so you get null reference exception. 
    

    This should be something like

    Holder holder = new Holder { someInterface = new SomeClass(){ Property = 1 } };//<--Note the new keyword here
    

    Note: Your code never introduced "Anonymous Type" It is an "Object Initializer".

    When you use ObjectInitializer syntax with new keyword it means you're setting something, when you use ObjectInitializer syntax without new keyword it means you're reading something.

    0 讨论(0)
  • 2020-12-19 03:01

    It's worth noting why the compiler lets this behaviour. The reason being someInterface need not be null always. This is what object initializer syntax is translated to:

    Holder temp = new Holder(); //creates temp object calling default constructor
    temp.someInterface = yourValue;
    holder = temp; //finally assigned back to your variable.
    

    In your case someInterface is left uninitialized. But it need not be the case if you have your empty constructor initializing someinterface correctly.

    class Holder
    {
        public Holder()
        {
           someInterface = new Class();
        }
    
        public ISomeInterface someInterface{get; set;}
    }
    

    Now this works:

    Holder holder = new Holder { someInterface = { Property = 1 } };
    
    0 讨论(0)
提交回复
热议问题