2010-02-03 106 views
2

我有需要的对象被创建时要进行初始化的两个私人列表。第二个列表取决于第一个列表。我可以这样做:初始化私有成员C#

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

     ... 
    } 

第二个列表是只读的第一个包装。

我能想到的是C#将在此为了每次运行时执行该两行呢?

或者我应该把这个初始化在构造函数?

编辑:
对不起,愚蠢的问题。我试了一下,编译说:

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

关于您的编辑,请参阅下面的答案:http://stackoverflow.com/questions/2194531/initializing-private-members-c/21​​94559#2194559。 – jason 2010-02-03 19:04:13

回答

11

号如果你想基于类内的一个独立的变量初始化变量,你需要做到这一点在构造函数中:

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

} 

内联intializers总是在静态上下文中运行,这意味着您无法访问类中的成员变量。但是,在构造函数内部,您可以执行此操作。内联的初始化器将出现在构造函数之前,这就是为什么我可以将列表初始化就绪的原因。

+1

为什么downvotes?我真的很好奇...... – 2010-02-03 18:59:31

+0

经过11个月的会员资格,你应该对这里的沉默驾驶风格非常熟悉;) – 2010-02-03 19:01:38

+0

@Mehrdad:是的,但是我总是很好奇为什么人们随机抽查 - 所以我通常会问。我偶尔会得到回应;)[就我个人而言,当我因为理由而陷入低谷时,我喜欢,因为它通常是一个学习机会。] – 2010-02-03 19:04:38

1

是的,你应该把myReadOnlyList的初始化在构造函数中,但为了保持一致性我建议把无论是在构造函数中。

4

我可以期待c#在每次运行时都按这个顺序执行这两行吗?

是,实例变量初始化时的法律(见下文),在它们出现的顺序运行。我参考该规范的第10.11.2节:

这对应于在进入构造函数时和直接基类构造函数的隐式调用之前立即执行的赋值序列。变量初始值设定项按它们出现在类声明中的文本顺序执行。

但是,字段初始值设定项无法像您所做的那样引用非静态字段。您的代码不合法​​。这是规范的第10.5.5.2节:

实例字段的变量初始值设定项无法引用正在创建的实例。因此,在变量初始值设定项中引用它是编译时错误,因为变量初始值设定项通过简单名称引用任何实例成员的编译时错误。

关于你提到的第二个问题:

或者我应该把这个初始化在构造函数?

每以上,你别无选择。至少您必须在构造函数中初始化myReadOnlyList,因为它指向实例字段myList。为了清楚起见,我会把两者都放在构造函数中。

最后一个注释,在一个单独的问题上。即使下面是不合法的:

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

} 

这是因为你还没有宣布MyClass作为一个泛型类。将public class MyClass替换为public class MyClass<T>

+0

“是的,当合法的实例变量初始值设定项(见下文)按照它们的顺序运行出现。” - 侧注:部分类的不同“部分”中初始值设定项的评估顺序未定义。 – 2010-02-03 19:11:58