简体   繁体   中英

Initializing private members c#

I have two private lists that need to be initialized when object is created. Second list is dependent on first one. Can I do it like this:

  public class MyClass
  {
      private List<T> myList = new List<T>();
      private ReadOnlyCollection<T> myReadOnlyList = myList.AsReadOnly;

      ...
  }

Second list is read only wrapper around first one.

Can I expect that c# will execute this two lines in this order each time it is run?

Or should I put this initializations in constructor?

Edit:
Sorry for stupid question. I tried it and compiler says:

Error   1   A field initializer cannot reference the 
             non-static field, method, or property...

No. If you want to initialize a variable based on a separate variable within the class, you need to do this in the constructor:

public class MyClass 
{ 
    private List<T> myList = new List<T>(); 
    private ReadOnlyCollection<T> myReadOnlyList;
    public MyClass()
    {
        myReadOnlyList = myList.AsReadOnly; 
    }

} 

Inlined intializers are always run in a static context, which means you have no access to member variables within your class. Inside of a constructor, however, you can do this. The inlined initializers will occur before your constructor, which is why I could leave the list initialization in place.

Can I expect that c# will execute this two lines in this order each time it is run?

Yes, instance variable initializers when legal (see below) run in the order in which they appear. I refer you to section §10.11.2 of the specification:

This corresponds to a sequence of assignments that are executed immediately upon entry to the constructor and before the implicit invocation of the direct base class constructor. The variable initializers are executed in the textual order in which they appear in the class declaration.

However, a field initializer can not reference a non-static field as you have done. Your code is not legal. This is §10.5.5.2 of the specification:

A variable initializer for an instance field cannot reference the instance being created. Thus, it is a compile-time error to reference this in a variable initializer, as it is a compile-time error for a variable initializer to reference any instance member through a simple-name.

Regarding your second question:

Or should I put this initializations in constructor?

Per the above, you have no choice. At a minimum you must put the initialization of myReadOnlyList in the constructor as it refers to the instance field myList . For clarity, I would put both in the constructor.

One last note, on a separate issue. Even the following is not legal:

public class MyClass {
    private List<T> myList;public class MyClass
    private ReadOnlyCollection<T> myReadOnlyList;
    public MyClass() { 
        myList = new List<T>();
        myReadOnlyList = myList.AsReadOnly;

}

This is because you have not declared MyClass as a generic class. Replace public class MyClass with public class MyClass<T> .

是的,您应该将myReadOnlyList的初始化放在构造函数中,但为了保持一致性,我的建议将两者放在构造函数中。

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