简体   繁体   中英

Can you differentiate between a property set during object initialization and one set separately?

As much as I agree with downvoting a crappy question, is it really that bad to have a(nother) resource noting that the below compile essentially identically?

Is there a way to tell whether a property is being set like this

MyClass myClass = new MyClass() { Value = 5 };

or this

MyClass myClass = new MyClass();
myClass.Value = 5;

?

In my application, I need to use would prefer to use object initializer syntax, but I also need setter logic that only occurs during object construction.

I assume the answer is no, as (to my knowledge) the first is essentially a shortcut for the second. But otherwise I'll have to put logic in the setter that should only ever run once or change my initialization syntax — neither of which sound attractive.

There is no difference at all. Check the underlying IL :

// Code size       30 (0x1e)
.maxstack  3
.locals init ([0] class MyProj.MyClass myClass,
              [1] class MyProj.MyClass myClass2)
IL_0000:  nop
IL_0001:  newobj     instance void MyProj.MyClass::.ctor()
IL_0006:  dup
IL_0007:  ldc.i4.5
IL_0008:  callvirt   instance void MyProj.MyClass::set_Value(int32)
IL_000d:  nop
IL_000e:  stloc.0
IL_000f:  newobj     instance void MyProj.MyClass::.ctor()
IL_0014:  stloc.1
IL_0015:  ldloc.0
IL_0016:  ldc.i4.5
IL_0017:  callvirt   instance void MyProj.MyClass::set_Value(int32)
IL_001c:  nop
IL_001d:  ret

That is generated for below code:

MyClass myClass = new MyClass() { Value = 5 };
MyClass myClass2 = new MyClass();
myClass.Value = 5;

The object initializers are just syntactic sugar and they are created to simplify construction of objects when you're using an object.

However you can check the following post to see the benefit of using an Object Initializer :

Is there any benefit of using an Object Initializer?

You can use the initializer only if you have a setter defined. It is just a simplification for this:

var m = new MyClass();
m.MyInt = 3;

Apart from this you shouldn´t rely on this at all, you should however ensure that your setter is actually doing the right things (eg validate the new value). However when you want to ensure the property is only set during initialization why not use a readonly-property:

class MyClass
{
    privarte readonly int _myInt;
    public int MyInt { get { return this._myInt; } }
    public MyClass(int theValue) 
    {
        this._myInt = theValue; 
    }
}

Now you can only instantiate your class as follows:

var m = newMyClass(3);

making all worries about if the setter was called or if it even exist obsolete.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM