2010-12-11 11 views
4

私はLINQのようなシステムを構築しています。その中で、多態的なコールバックハンドラリストをサポートしようとしており、いくつかの種類の問題が発生しています。私の質問をする短い方法は、ちょうどあなたにいくつかのコードを示すことです。私の新しいシステムでは "Groups"がサポートされています。グループにはエントリポイントのベクトル(下のUPDATEとCHECKPT)があり、ベクトルの各要素は多面的なデリゲートのリストです。C#:デリゲートリストを作成するための醜い構文ですか?

ので、サンプルコード:

namespace ConsoleApplication1 
{ 

    internal delegate void GroupISDHandler(int i, string s, double d); 
    class Group 
    { 
     public class myHandlers { 
      internal List<Delegate> hList = new List<Delegate>(); 
      public static myHandlers operator +(myHandlers a, Delegate b) { 
       a.hList.Add(b); 
       return a; 
      } 
     } 

     public class mimicVector { 
      public List<myHandlers> ListofhLists = new List<myHandlers>(); 
      public myHandlers this[int i] { get { return ListofhLists[i]; } set { ListofhLists[i] = value; } } 
     } 

     public mimicVector handlers = new mimicVector(); 

     public Group(string name) { ... } 
    } 

    class Program 
    { 
     internal const int UPDATE = 0; 
     internal const int CHECKPT = 1; 

     public static void Main() 
     { 
      Group g = new Group("group name"); 
      g.handlers[UPDATE] += (GroupISDHandler)delegate(int x, string s, double d) { 
       Console.WriteLine("my int,string,double handler was called, with x = {0}, s = {1}, d = {2}", 
        x,s,d); 
      }; 
     } 
    } 
} 

私の質問は、登録ラインを中心。なぜC#で型を推論できないので、キャストと新しいデリゲート型を完全に省略することができますか?私はそう思うでしょう。

g.handlers[UPDATE] += delegate(int x, string s, double d) { 
    Console.WriteLine(....); 
}; 

C#は、必要な型名を推論することができます。デリゲートは、()だけ

private delegate void _atype1(int _a0, string _a1, double _a2) 

のようなものを生成して、行をコンパイルする前に(Delegate)(_atype1)を挿入する匿名型とC#のようなものだろう。したがって、私のユーザはデリゲート型を宣言する必要はありません(現在は、引数リストを2回タイプする必要があります)。

LINQは何とか必要なキャストを推測することができる場合、私はそうVS 2010上でだので、私はあなたがそれをこの方法で行うことができるはず...

+0

キャストを取り除きたいと気付いただけで、なぜパラメータが必要ですか?あるいは彼らはいつも3になるだろうか? –

+0

パラメータは異なります。 1つの着信メッセージはintと文字列を持つことがあります。秒はFooBarsの配列などを持つかもしれません。私の配送ロジックはそれぞれのマッチに対してアップコールを行います。 –

+0

(ちょっとした説明を追加してください:アップコールを引き起こす受信​​メッセージには、これらのコールバックの少なくとも1つと一致する必要があるデータが含まれています。)グループにマルチキャストを送信すると、それで、パラメータはメッセージから来て、それらの型は一致します)。 –

答えて

0

答えは基本的には次のようになります。私が思いついた状況の推論を行うことができますが、C#の所有者は完全な一般的な解決法を望んでおり、多型は型推論の問題を十分に解くのが難しい彼らの見解では、一般的な方法です。私はすべてのタイプの署名を2回タイプすることになってしまったので私自身は同意しませんが、それは彼らの推論です。

2

System.Linqを持っています:

g.handlers[UPDATE] += (GroupISDHandler)((x, s, d) => Console.WriteLine( "my int,string,double handler was called, with x = {0}, s = {1}, d = {2}", x, s, d));

別のオプションは次のようになります:

ユーザーが送信できるもののコンテナである「パラメータ」という名前のクラス、変更しない場合は型の定義されたクラス、異なる送受信のふりをする場合はオブジェクトのリストがありますパラメータの量代理人の代わりに、1つの引数を取る代理人に等しいActionを取ると、次のようにキャストすることなく呼び出しを行うことができます。

p => Console.WriteLine( "x = {0}、s = {1}、d = {2} "、px、ps、pd);

+0

それは興味深い考えです。このバージョンでは、私のユーザはキャストを必要としますが、パラメータタイプの指定を避けることができ、 "代理人"と言う必要はありません。私はすきです。かなりちょっとちがう。それでも、宣言がコードから遠く離れていることは残念です。これを見ている人はx、s、dの型を知ることができません。 –

関連する問題