Philisophical问题[编辑] [英] Philisophical question [edited]

查看:88
本文介绍了Philisophical问题[编辑]的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有两种方法可以通过构造函数初始化C#类中的成员:

There are two ways to initialize members in a C# class, via constructor:

class MyClass{
  private int Member;
  public MyClass()
  {
    Member = 0;
  }
}



或通过会员初始化:


or through member initialization:

class MyClass
{
  private int Member = 0;
}



我的问题:一种方法与另一种方法有问题/好处吗?



从我所看到的情况来看,如果你只有一个默认构造函数,它就是一个清洗。如果你有多个构造函数,那么成员初始化对于那些被所有构造函数设置为相同值的成员更可取。


My question: Are there problems / benefits of one approach vs. another?

From what I can see, it's a wash if you only have a default constructor. If you have multiple constructors, member initialization is preferable for those members that are set to the same value by all constructors.

推荐答案

Gary,

如果该类调用Finalize,然后使用成员初始化肯定是正确的方法。原因是,如果构造函数中存在错误,并且调用了Finalize,那么字段的状态可能会起作用。在这种情况下使用成员初始化意味着您知道您的字段是有效的,因此如果在失败的对象构造后调用finalize,则不会出现问题。

D.


Gary,

If the class calls Finalize, then using member initialization is certainly the right way to go. The reason being, if there is an error in the constructor, and Finalize is called, then the state of the fields could come into play. Using member initialization in this case means that you know your fields are valid, so you won't have issues if finalize is called following failed object construction.

D.



最后修改:最初发布后12分钟 -






我不知道认为这真的很重要,特别是在将变量设置为默认值的情况下(建议不要这样做)。如果您有多个构造函数,则可以在最简单的构造函数中设置初始值,然后使用构造函数链接。在你的第一个例子中,你实际上在构造函数中最后添加3行IL以处理将争论加载到评估堆栈(它已经执行),然后将0作为整数加载到评估堆栈,然后用新值替换存储在Member字段中的值。

I don't think it really matters, especially in the case of setting variables to their default values (which is recommended to not do). If you have multiple constructors, you can set the initial values in your simplest constructor and then use constructor chaining. In your first example, you actually end up with 3 additional lines of IL in the constructor to handle loading the arguement on to the evaluation stack (which it already does), then loading the 0 as an integer on to the evaluation stack, and then replacing the value stored in the "Member" field with the new value.


如果从构造函数中调用虚方法,则会有一个细微的差别,这通常是不可取的。在为构造函数生成IL代码时,C#编译器会在构造函数体的代码之前为所有字段初始值设定项放置代码。这意味着重写将看到字段初始化成员的初始化值,但会看到其他成员的默认值。

There's a subtle difference if you call virtual methods from your constructor, which is generally not advisable. When generating IL code for the constructor, the C# compiler puts code for all field initializers before code for the constructor's body This means that overridden will see initialized values for field initialized members, but will see default values for others.

<br /><br />class Base<br />{<br />   protected int x = 42;<br />   protected int y;<br /><br />   public Base()<br />   {<br />      SomeVirtualMethod();<br />      y = 42;<br />   }<br /><br />   protected virtual void SomeVirtualMethod() {}<br />}<br /><br />class Derived : Base<br />{<br />   protected override void SomeVirtualMethod()<br />   {<br />      Console.WriteLine(x);<br />      Console.WriteLine(y);<br />   }<br />}<br /><br />



打印42和0.



prints 42 and 0.


这篇关于Philisophical问题[编辑]的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆