English 中文(简体)
使用“this”进行构造函数链接
原标题:
  • 时间:2009-03-25 12:42:30
  •  标签:

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

或者我怎样才能使它工作?

谢谢 (xiè xiè)

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指的是尚未实例化的对象(对象的创建直到某个(顶层或基本)构造函数块被输入才开始)。此外,你为什么要这样做呢?如果你可以在任何地方访问this关键字,这似乎是毫无意义的。

我建议只使用独立的构造函数,如下:

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

    public ClassA()
    {
        _methodA = this;
    }

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

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

问题回答

你可以使用this(...)语法在同一级别调用另一个构造函数 - 不过,你不能在这种情况下使用this(当前实例)。

在这里最简单的选项是复制任务代码(_methodA = methodA)。

另一个选项可能是Null Coalescing:

public ClassA():this(null)
{}

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

这在 C# 规范的第10.11.1节中被称为。

An instance constructor initializer cannot access the instance being created. Therefore it is a compile-time error to reference this in an argument expression of the constructor initializer, as is it a compile-time error for an argument expression to reference any instance member through a simple-name.

没有办法使用实例构造函数使其工作,因为它无法访问。您可以做的是使构造函数私有化,创建初始化方法和静态构造函数。

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;
  }




相关问题
热门标签