2012-03-21 23 views
0

私は、デリゲートを宣言:デリゲートに追加された関数が静的である必要があるのはなぜですか?

public delegate void Del(string message); 

その後、私は私がデリゲートに追加したい機能を作成しました:

public static void DelegateMethod(string message) 
{ 
    System.Console.WriteLine(message); 
} 

今、私は、デリゲートに機能を追加し、それを呼び出す:

Del handler = new Del(DelegateMethod); 
handler("Hello World"); 
Console.Read(); 

DelegateMethodからstaticを削除するとエラーが表示されるのはなぜですか?

私が委任する関数は静的でなければならないのはなぜですか?

+0

どの範囲でハンドラを追加しているのでしょうか? –

+0

重複 - http://stackoverflow.com/questions/2298997/why-cant-a-delegate-refer-to-a-non-static-method-when-used-in-static-method – scibuff

+2

多分あなたは静的なクラス/関数内からコードを呼び出していますか?私はVSのコンソールアプリケーションのデフォルトだと思います(あなたの 'Main'関数は静的です)。非静的関数は、それらを含むクラスのインスタンスを持っているときにしかアクセスできません。 – musefan

答えて

3

DelegateMethodから「静的」をドロップするとエラーが表示されるのはなぜですか?

このコードを静的メソッド内に記述しているためです。 Console.Readを使用しているという事実を考えると、このコードをコンソールアプリケーションのstatic void Mainメソッドの中に入れていると思います。 のメソッドから削除する場合は、このメソッドを含むクラスのインスタンスが必要です。このように:

class Program 
{ 
    public delegate void Del(string message); 

    public void DelegateMethod(string message) 
    { 
     System.Console.WriteLine(message); 
    } 

    static void Main() 
    { 
     Del handler = new Del(new Program().DelegateMethod); 
     handler("Hello World"); 
     Console.Read(); 
    } 
} 
1

静的メソッドを使用する必要があるデリゲートについて間違っています。

デリゲートと互換性を持たせるには、メソッドのシグネチャ(戻り値の型と型 - 型、番号、順序)が一致する必要があります。 MSDNから

からDelegates (C# Programming Guide)

戻り型とパラメータで構成デリゲートの署名を、一致するアクセスクラスまたは構造体の任意の方法が、デリゲートに割り当てることができます。 このメソッドは、静的メソッドまたはインスタンスメソッドのいずれかになります。

(強調鉱山)


デリゲート対象としてインスタンス方法を使用して、あなたは実際のインスタンスを参照する必要があります。

public class MyClass 
{ 
    public static void DelegateMethod(string message) 
    { 
     System.Console.WriteLine(message); 
    } 
} 

var myClass = new MyClass(); 
Del handler = new Del(myClass.DelegateMethod); 
+0

@Downvoter - 説明するケア? – Oded

+0

ジェイソンはここで私たちが説明しようとしていることを理解していないので、ここでdownvote酒宴に行ったように見えます。 –

+0

@ØyvindKnobloch-Bråthen - いいえ、私は彼が何を意味するかを見ていますが、彼は下降音に喜んでいます。 – Oded

0

だけで推測をここに。このコードを含むメソッドは:

Del handler = new Del(DelegateMethod); 
handler("Hello World"); 
Console.Read(); 

静的でもありますか?その場合、静的メソッドから非静的メソッドを参照することはできないため、DelegateMethodも静的でなければなりません。

+0

彼は包含クラスのインスタンスへの明示的な参照を持つことができます。 – jason

+1

これはあなたの答えと同じように真実です。上記のコードは、例えば、コンソールアプリケーションのmainメソッドの中に置くことができます。しかし、ねえ、downvoteのおかげで。 –

+0

@ yvind:ありがとう、私は誰がこれをdownvotedか分からないが、あなたも正しい答えを持って、ありがとう。 – Rodniko

1

静的である必要はありませんが、非静的メソッドではインスタンスが必要です。これは、非静的(インスタンス)メソッドの定義です。あなたはこのようなデリゲートにインスタンスメソッド(およびインスタンス)を渡すことができます。

Del handler = new Del(instanceVariable.DelegateMethod); 

あなたは、同じクラスの他のインスタンスメソッドに委譲しにインスタンスメソッドを追加することができます。インスタンスはこれと仮定しています。

デリゲートインスタンスが存在する限り、このようにしてインスタンスはGCに適格ではないことに注意してください。これは、時々、オブジェクト漏れの理由(一部の人は漏れがより高いレベルにあり、Cスタイルのメモリリークと異なっているという事実にもかかわらず、メモリリークそれらを呼び出す)

+0

これはどちらでもかまいません。 – Oded

+0

申し訳ありませんが、私はそれを逃した。どちらか? – Stilgar

+1

あなたは「インスタンスが必要です」と言っています。それはしません。静的メソッドまたはインスタンスメソッドにすることができます。 – Oded

1

なぜ私は「静的」をドロップしたときでありますDelegateMethodからエラーが表示されますか?

あなたは混乱しているエラーを正確に指定しませんでした。

Del handler = new Del(DelegateMethod); 

理由:私はあなたが混乱しているエラーがDelegateMethodstaticではなく、あなたが含むクラスでstaticメソッド内のコードの行を書いている場合は、この行がコンパイルされないという事実である疑いがありますDelegateMethodstaticと宣言しないと、メソッドを参照するインスタンスが必要になるためです。コードが含まれているクラスのstaticメソッドで書かれている可能性が高い場合、暗黙的にthisが存在しないため、明示的なインスタンスが必要です。お使い含むクラスがFoo命名されたと仮定すると:

Foo foo = new Foo(); 
Del handler = ne Del(foo.DelegateMethod); 

参照してください?

+0

しかし、コードは静的メソッド内にあるため、他の静的メソッドにしかアクセスできないこともあります。見る? –

+0

あなたは私の答えを十分に注意深く読まなかったのですか?私はその点に取り組んだ。 – jason

関連する問題