2016-05-02 15 views
25

私は最近C#で作業を始めましたが、私がC#で実現したいPythonで簡単にやったことがあります。辞書と関数

def my_func(): 
return "Do some awesome stuff" 

などの辞書::私は、プログラムをユーザーが入力が「やる」ことになるでスクリプトを作った

my_dic = {"do": my_func} 

例えば、私のような機能を持っていますその辞書に従ってmy_funcと呼ぶ。

C#辞書の文字列に関数を割り当てる方法を知りたいと思います。基本的には同じように

+0

@SiyavashHamdi:そうではありません。標準の 'Action'や' Func'のような代理人が必要です。または '表現'です。もちろん、これらはすべて内部的には反射に基づいています。なぜなら、 'MethodInfo'はこれらのそれぞれの中にあるからです。しかし、手動でそれを見つける/呼び出すようなものではありません。 – quetzalcoatl

+2

参照:[代理人](https://msdn.microsoft.com/library/ms173171.aspx)、特に組み込みの汎用代理人の種類[操作](https://msdn.microsoft.com/library/system) action.aspx)( 'void'戻り型のメソッドの場合)と[Func](https://msdn.microsoft。com/de-de/library/bb534960.aspx)(戻り値の型がvoidでないメソッドの場合)およびそれらのオーバーロードが多数あります。 – Corak

答えて

50

:あなたがここにコレクション初期化子構文を利用することができ

static void Main() { 
    var dict = new Dictionary<string, Action>(); 
    // map "do" to MyFunc 
    dict.Add("do", MyFunc); 
    // run "do" 
    dict["do"](); 
} 

static void MyFunc() { 
    Console.WriteLine("Some stuff"); 
} 
+3

ラムダ式を使うこともできます: 'dict.Add(" do "、()=> Console.WriteLine(" Some stuff "));'。ここで重要な点は、 'Action'はデリゲート型であり、関数がパラメータを取らず結果を返す必要がないことを指定しています。引数を取ることを可能にする他の一般的なバージョンの 'Action'があり、' Func'は値を返すことを可能にします。また、これが機能するには、すべての関数が同じパラメータセットと出力タイプを必要とすることにも注意してください。 – jpmc26

+1

Pythonとは異なり、C#は途中で複数のlambdaを持っています:()=> {Console.WriteLine( "A"); Console.WriteLine( "B"); }、それは創作者の「腸の感覚」によって制限されないからです。 – Traubenfuchs

+0

@Traubenfuchs Pythonに公平になるためには、ずっと前に 'def'を使って任意のスコープで複数の関数を実行することができました(私は)' lambda'が言語に追加されたと思います。したがって、ラムダを非常に簡単な操作をインライン化するための便宜とみなし、マルチエクスプレッションラムダが多分構文解析を複雑にするか、シンタックス要素を必要とするという事実には限界があります。対照的に、C#では関数スコープ内に通常の関数(クラスの一部)を定義することはできませんので、C#ではラムダ関数がPythonでより多くの役割を果たすようになります。 – jpmc26

18

。より洗練された機能については

var my_dic = new Dictionary<string, Action> 
{ 
    { "do", my_func } 
}; 

、あなたは適切なFunctionタイプと宣言してActionを交換したいです。あなたの例に最も直接的に類似しただろう

+0

単純なケースでは、コレクションイニシャライザでラムダ構文を使用することもできます(場合によってはメソッドグループの名前を書きます) – kai

5

C#のコードフラグメントは、次のとおりです。

string my_func() { 
    return "Do some awesome stuff"; 
} 

そして:

var my_dic = new Dictionary<string, Func<string>> { 
    { "do", my_func }, 
}; 

トリック他のポスターが指摘したように、作成することです。汎用値型がAction(voidを返すメソッド)またはFunc <T>(T型のオブジェクトを返すメソッド)のいずれかの文字列です。あなたが本当にパイソンの動的挙動をしたい場合は

var result = my_dic["do"](); 
+0

EvkとAdam Eの回答に非常に似ていますが、 Balgyによって提供された例のダイレクトコードアナログ。 –

2

は(すなわちシームレス割り当て、「辞書に異なるシグネチャを持つメソッドを呼び出すことができること:いずれの場合も

は、あなたがしてメソッドを実行することができます")、私はPythonなどの動的言語をCLRでサポートできるように特別に設計されたExpandoObjectを使用します(IronPythonなど参照)。

static void Main() 
{ 
    dynamic expando = new ExpandoObject(); 
    expando.Do = new Func<string>(MyFunc); 
    expando.Do2 = new Func<string, string>(MyFunc2); 

    Console.WriteLine(expando.Do()); 
    Console.WriteLine(expando.Do2("args")); 
} 

static string MyFunc() 
{ 
    return "Do some awesome stuff"; 
} 

static string MyFunc2(string arg) 
{ 
    return "Do some awesome stuff with " + arg; 
} 

必要であれば、あなたも辞書としてExpandoObjectを扱うことができます。

static void Main(string[] args) 
{ 
    dynamic expando = new ExpandoObject(); 
    var dict = (IDictionary<string, object>) expando; 
    dict["Do"] = new Func<string>(MyFunc); 
    dict["Do2"] = new Func<string, string>(MyFunc2); 

    Console.WriteLine(expando.Do()); 
    Console.WriteLine(expando.Do2("args")); 
} 

static string MyFunc() 
{ 
    return "Do some awesome stuff"; 
} 

static string MyFunc2(string arg) 
{ 
    return "Do some awesome stuff with " + arg; 
} 

が**編集**

全開示:この質問はだまされやすい人でない場合(非常に似ているようです)のString- Function dictionary c# where functions have different argumentsです。私はちょうど同じ方法で答えました。

関連する問題