views:

247

answers:

4

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...
+8  A: 

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.

Reed Copsey
Why the downvotes? I'm really curious...
Reed Copsey
@Reed: After 11 months of membership, you should be quite familiar with silent drive-by downvoters here ;)
Mehrdad Afshari
@Mehrdad: Yeah, but I always am curious as to why people are downvoting randomly - so I usually ask. I do, occasionally, get a response ;) [Personally, I love when I get downvoted with reason, since it's usually a learning opportunity.]
Reed Copsey
+2  A: 

To be honest the best answer anyone here could/should give you is, try it

Kristoffer S Hansen
While "try it" seems like an obvious response, people tend to ask these kinds of questions because they are hoping that the answer will be accompanied by an explanation as to why/why not.
Joel Etherton
+1  A: 

Yes, you should put the initialization of myReadOnlyList in a constructor, but for consistency my recommendation put both in constructor.

Alex LE
+3  A: 

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>.

Jason
"Yes, instance variable initializers when legal (see below) run in the order in which they appear." -- side note: order of evaluation of initializers in different "parts" of a partial class is undefined.
Mehrdad Afshari