C# 带“的构造函数链接”;这";

C# 带“的构造函数链接”;这";,c#,c#-3.0,C#,C# 3.0,为什么ClassA中的第一个构造函数会导致编译器错误“无法在成员初始化器中使用”this“ 。。。或者我怎样才能让它工作 谢谢 public sealed class ClassA : IMethodA { private readonly IMethodA _methodA; public ClassA():this(this) {} public ClassA(IMethodA methodA) { _methodA = metho

为什么ClassA中的第一个构造函数会导致编译器错误“无法在成员初始化器中使用”this“

。。。或者我怎样才能让它工作

谢谢

public sealed class ClassA : IMethodA
{
    private readonly IMethodA _methodA;

    public ClassA():this(this)
    {}

    public ClassA(IMethodA methodA)
    {
        _methodA = methodA;
    }

    public void Run(int i)
    {
        _methodA.MethodA(i);
    }

    public void MethodA(int i)
    {
        Console.WriteLine(i.ToString());
    }
}

public interface IMethodA
{
    void MethodA(int i);
}

您可以使用
this(…)
语法来调用同一级别的另一个构造函数-但是,您不能在此上下文中使用
this
(当前实例)

这里最简单的选项是复制分配代码(
\u methodA=methodA

另一个选项可能是空合并:

public ClassA():this(null)
{}

public ClassA(IMethodA methodA) 
{ // defaults to "this" if null
    _methodA = methodA ?? this;
}

规范第10.11.1节对此进行了规定

实例构造函数初始值设定项 无法访问正在创建的实例 创建。因此,它是一个 引用此文件的编译时错误 在参数表达式中 构造函数初始值设定项,因为它是 参数的编译时错误 表达式引用任何实例 成员通过一个简单的名称

无法将其与实例构造函数一起使用,因为无法访问它。您可以做的是使构造函数私有,创建一个初始化方法和一个静态构造函数

public sealed class ClassA : IMethodA {    
  private ClassA() { }
  private void Initialize(IMethodA param) { ... }
  public static ClassA Create() {
    var v1 = new ClassA();
    v1.Initialize(v1);
    return v1;
  }
  public static ClassA Create(IMethodA param) {
    var v1 = new ClassA();
    v1.Initialize(param);
    return v1;
  }
}

您试图在构建对象之前传递该对象。虽然编译器在这种情况下可以做一些合理的事情,但一般来说,这是行不通的

如果您只需执行以下操作,您的实际示例就会起作用:

   public ClassA()
  {
    _methodA = this; 
  }
但是您可能想要共享更多的逻辑,所以只需使用函数

  public ClassA()
  {
    SetStuff(); 
    _methodA = this; 
  }

  public ClassA(IMethodA methodA)
  {
    SetStuff(); 
    _methodA = methodA;
  }

链接构造函数时不能使用
this
关键字,因为
this
引用了一个尚未实例化的对象(在输入一些(顶级或基本)构造函数块之前,对象的创建不会开始)。而且,你到底为什么要这么做?当你到处都可以访问
this
关键字时,这似乎毫无意义

我建议简单地使用独立构造函数:

public sealed class ClassA : IMethodA
{
    private readonly IMethodA _methodA;

    public ClassA()
    {
        _methodA = this;
    }

    public ClassA(IMethodA methodA)
    {
        _methodA = methodA;
    }
}

也许我误解了您的意图,但希望这能为您解决问题。

请注意,您仍然可以将SetStuff与只读字段一起使用。。。如果使用
ref
/
out
参数。这是否值得取决于具体情况。