2009-03-25 4 views
3

なぜClassAの最初のコンストラクタでコンパイラエラーが発生しましたか? 'これをメンバの初期化で使用できません'?"this"で連結されたコンストラクタ

...またはこれを動作させるにはどうすればよいですか?しかし、あなたはこの文脈で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); 
} 

答えて

1

)コンストラクタブロックが入力されました)。さらに、なぜこれをやりたいのですか?どこでもthisキーワードにアクセスすると、無意味なようです。

私は単にのような独立したコンストラクタを使用することをお勧めします:

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

    public ClassA() 
    { 
     _methodA = this; 
    } 

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

おそらく、私はあなたが何をしようとして誤解し、うまくいけば、あなたのための問題を解決すること。

9

あなたは同じレベルで別のコンストラクタを呼び出すためにthis(...)構文を使用することが許可されています。

ここで最も簡単なオプションは、割り当てコード(_methodA = methodA)を複製することです。

別のオプションは、nullで合体かもしれません:

public ClassA():this(null) 
{} 

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

@Marc Gravell:それに私を打ちなさい... –

3

これは が作成されるインスタンスのコンストラクタ初期化子 がインスタンスにアクセスすることはできませんC#の仕様

のセクション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; 
    } 
} 
3

オブジェクトを作成する前に渡すとしています。コンパイラは、この場合は賢明な何かをすることができますが、一般的にはうまくいかないでしょう。

public ClassA() 
    { 
    _methodA = this; 
    } 

しかし、あなたはおそらく関数を使用するので、より多くのロジックを共有したい:あなただけのこの操作を行う場合

あなたの実際の例が動作します。基本的にコンストラクタを連鎖するときthisがまだインスタンス化されていないオブジェクトを参照するので、あなたは、オブジェクトの作成には、いくつかの(トップレベルまたはベースまでは始まらない(thisキーワードを使用することはできません

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

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

'ref' /' out'引数を使用すると、あなたは引き続きreadonly fields ... *でSetStuffを使うことができます。それが価値があるかどうかは、シナリオによって異なります。 –