Constructor chain with "this"

Why does the first constructor in ClassA cause a compiler error 'can't use this in member intializer'?

... or how can I make this work?

thanks

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);
}
+3
source share
4 answers

You cannot use the keyword thiswhen creating chain constructors because it thisrefers to an object that has not yet been created (object creation does not start until some constructor block (top or base) has been entered). Moreover, why exactly do you want to do this? It seems pointless when you have access to a keyword this.

:

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

    public ClassA()
    {
        _methodA = this;
    }

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

, , , , , .

+1

this(...) , this ( ) .

- (_methodA = methodA).

:

public ClassA():this(null)
{}

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

10.11.1 #

, . , .

It is impossible to get this to work with the instance constructor because it cannot be accessed. What you can do is make the constructor private, create an initialization method and a static constructor.

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;
  }
}
+3
source

You are trying to transfer an object before it is created. Although the compiler could do something sensible in this case, in general, this will not work.

Your actual example works if you only do this:

   public ClassA()
  {
    _methodA = this; 
  }

But you probably want to share more logic, so just use the function.

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

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

Source: https://habr.com/ru/post/1705334/


All Articles