初めて自分の家と他人の家が違う、と意識した時

C#におけるdelegateという仕様って
javascriptやPHPにおける無名関数と同じものとおもってさしつかえないのでしょうか?

たとえば
(1)
var funcObj = function (){
alert("無名関数だよ");
};
funcObj();
ーーーーーーーーーーーーーーーーー
(2)
$func =function(){
print("無名関数");
};
$func();


といった類のもの?

たとえば以下のようなC#のコードだと
using System;


class MainClass{


//delegateの宣言
public delegate void MyMethod(string message);
public delegate void NoneMethod(string aaa);


public static void Main (string [] args){

//delegateの中身を記述
MyMethod methodA = delegate(string messageA){
Console.WriteLine(messageA);
};
//無名関数?として実行
methodA("無名関数?");


//delegateをnewして使用する。
NoneMethod obj =new NoneMethod(OriginalMethod);
obj("newして利用する無名関数");
}

//delegateの中身を記述
public static void OriginalMethod(string aaa){
Console.WriteLine(aaa);
}
}

二種類delegateとおもわれるコードを書いております。
この delegateというキーワードをつかってまさに、冒頭のjsやPHPのようなスクリプト言語の
ような感じで定義するdelegateと

宣言したdelegateを newしてまるでクラスのように扱う方法
のdelegate
この二つの違いはなんでしょうか?

バージョンによる、あたらしいか古いかだけですか?

A 回答 (1件)

まず,デリゲート自体はメソッドの呼び出し機構をオブジェクト化したものです。


イベントハンドラやコールバック関数などに使われることが多いです。
その他,スレッドプールを利用したマルチスレッドの実行にも使うことができます。


で,元々 (C# 1.0~) あるのが,デリゲート型を定義するためのdelegateです。
> public delegate void MyMethod(string message);
> public delegate void NoneMethod(string aaa);
で使っている物です。

C#は基本的に型ベースなので,このような定義が必要になります。
ただし,.NET 3.5以降ではAction<T>やFunc<T, TResult>といったような汎用デリゲート,
さらにはイベントハンドラ用のEventHandler<T>などがあるため,
outやrefなどが不要であれば定義することはないでしょう。
# .NET 4ではAction<T1, T2, ..., T16>なんていうのが追加されました……。

.NET 2.0でPredicate<T>のようなデリゲートが追加されましたが,
.NET 3.5のSystem.Linq.Enumerable.WhereはPredicateではなくFuncを引数にとるようになっていたりします。

ちなみに,C# 2.0でメソッドからデリゲートを生成する場合にnewは不要になりました。
> NoneMethod obj =new NoneMethod(OriginalMethod);

NoneMethod obj = OriginalMethod;
と書けます。


delegateを使った匿名関数は,C# 2.0で追加された新機能ですが,C# 3.5でラムダ式が入って不要になりました。
> MyMethod methodA = delegate(string messageA){
> Console.WriteLine(messageA);
> };
は,
Action<string> methodA = messageA => Console.WriteLine(messageA);
または
Action<string> methodA = messageA => { Console.WriteLine(messageA); };
と書けます。

どちらも実体はコンパイラが頑張ってくれる物です。
おそらく,
private void methodA_Impl (string messageA) { Console.WriteLine(messageA); }
なんていうようなメソッドを生成して,
MyMethod methodA = new MyMethod(methodA_Impl);
のように変換してくれています。

この回答への補足

ありがとうございます。

コントロールごとのClickなどのイベントもdelegate(){}
で内容を記述することによって同様の動きができました。
ありがとうございます。

補足日時:2012/10/18 21:58
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!


おすすめ情報