【问题标题】:Is it okay to refer to "this" in the constructor?可以在构造函数中引用“this”吗?
【发布时间】:2011-07-02 13:22:58
【问题描述】:

在 C# 中,我使用的一种常见模式是使用表单对象填充较低计算类的详细信息。

MyForm 的构造函数是:

MyForm()
{
   _MyFormCalcs = new MyFormCalcs(this);
}

但是我今天遇到了一个错误,这让我觉得我的构造函数还没有完成,它创建了一个新的 MyForm 实例来传递给 MyData。因此它调用了构造函数两次。我发现 MyFormCalcs 中的静态列表被填充了两次,第二次失败了,因为列表中已经存在键。

我可以在构造函数中使用 this 来引用这个实例吗?它将包含在较低类中的内容 - 构造函数是否已运行。

将我的表单传递给下层的更好方法是什么?

【问题讨论】:

    标签: c# .net winforms constructor this


    【解决方案1】:

    不,这不会创建 MyForm 的新实例。

    一般来说,允许this 从构造函数中“退出”是dangerous,因为这意味着它可以在构造函数完成之前使用,但不会创建新实例。如果您可以给出一个简短但完整的示例来说明您所看到的问题,我们可以帮助您进一步诊断。特别是,不清楚“静态列表被填充两次”是什么意思。通常在 instance 构造函数中填充 static 变量并不是一个好主意。

    【讨论】:

    • 同意,而且,如果你能确保它是最后执行的语句,应该没有任何其他问题。
    • @astander:嗯,除了 .NET 内存模型的正常保证不会被应用......不太可能咬你,但仍然可能。
    • 是的,比抱歉更安全X-)
    • @Jon:有时它很危险,但有时没有太多其他选项可用...对于父子关系(或容器-容器关系),父子关系都需要引用为了构成有效的对象,没有办法解决这个问题。 :\
    • @astander:你无法确定你的类是否是子类。
    【解决方案2】:

    事实上,在构造函数中避免这样的调用真的很好,因为你的对象还没有被构建(构造函数还没有完成它的工作)但是你已经使用这个“未完成”的对象作为参数。这是一个糟糕的方式。好的方法是创建一些特殊的方法:

    class MyClass
    {
    
     var obj:SomeClass;
    
      public MyClass()
      {
      }
    
      public Init()
      {
        obj = SomeClass(this);
      }
    
    }
    

    【讨论】:

      【解决方案3】:

      创建一个私有属性,仅在第一次使用时实例化 MyFormCalcs,如下所示:

      public class MyForm {
      
        private MyFormCalcs MyFormCalcs {
          get {
            _MyFormCalcs = _MyFormCalcs ?? new MyFormCalcs(this);   
          }
        }
      }
      

      这样,您不必考虑何时“初始化”事物。

      【讨论】:

        【解决方案4】:

        C#构造函数顺序有这个非常完整的响应:

        C# constructor execution order

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-09-02
          • 1970-01-01
          • 2011-10-21
          • 2016-07-21
          • 2010-12-19
          • 1970-01-01
          相关资源
          最近更新 更多