2011-02-01 5 views
4

Pythonには、オブジェクトが関数のように呼び出されたときに呼び出されるこの魔法の__call__メソッドがあります。 C#は何か類似していますか?C#は__call__メソッドをサポートしていますか?


具体的には、代理人とオブジェクトを同じ意味で使用する方法を期待していました。ユーザーが関数のリストを渡すことができるAPIを設計しようとしましたが、時にはそれらの関数がいくつかの初期パラメータを必要とすることがありました。その場合、代わりにそれらの呼び出し可能オブジェクトの1つを使用します。

+0

+1恐ろしい質問があります。 – ClosureCowboy

答えて

4

私はサイモンスベンソンに屈するない - ビューのより海峡前方非動的ポイントのために - あなたはDynamicObjectから継承する場合は、それを行う方法を示しています

申し訳ありませんが、何も - それができるオブジェクトの種類がありますたとえば、代理人と呼ばれる。

Func<int, int> myDelagate = x=>x*2; 
int four = myDelagate(2) 

ありただし、デフォルトのプロパティである - 少なくとも1つのパラメータを持っている必要があり、そのアクセスは、配列アクセスのようになります。

class Test1 
{ 
    public int this[int i, int j] 
    { 
     get { return i * j; } 
    } 
} 

は次に、あなたが行うことができます

 Test1 test1 = new Test1(); 
     int six = test1[2, 3]; 

を呼び出します次のような代理人と実際に馬鹿なもの:

class Test2 // I am not saying that this is a good idea. 
{ 
    private int MyFunc(int z, int i) 
    { 
    return z * i; 
    } 
    public Func<int, int> this[int i] { get { return x => MyFunc(x, i); } } 
} 

そして、それはこのような奇妙に見える呼び出す:

 Test2 test = new Test2(); 
     test[2](2); // this is quite silly - don't use this..... 
3

これは、関数呼び出し演算子をオーバーロードに似だろう(C++で可能であるとして)。残念ながら、これはC#でサポートされているものではありません。メソッドのように呼び出すことができる唯一のオブジェクトはデリゲートのインスタンスです。

+0

私は幸いにもあなたはC#でこれを行うことはできません - を除いて2番目のだろう - 私はあまりにも忍者を渡っていない願っています。 :) – Neil

5

確かに、あなたがDynamicObjectを継承している場合。私はあなたがobj(...)上で実行TryInvoke後にしていると思いますが、あなたはキャスト処理するためにオーバーライドすることができ、他のいくつかの方法で、インデックスアクセス(obj[idx])、メソッド呼び出し、プロパティの呼び出しなど

using System; 
using System.Diagnostics; 
using System.Dynamic; 
using System.Linq; 
using System.Text; 

namespace ConsoleApplication { 
    public static class ConsoleApp { 
     public static void Main() { 
      dynamic x = new MyDynamicObject(); 
      var result = x("awe", "some"); 

      Debug.Assert(result == "awesome"); 
     } 
    } 

    public class MyDynamicObject : DynamicObject { 
     public override Boolean TryInvoke(InvokeBinder binder, Object[] args, out Object result) { 
      result = args.Aggregate(new StringBuilder(), (builder, item) => builder.Append(item), builder => builder.ToString()); 
      return true; 
     } 
    } 
} 
+0

+1うわー! - ダイナミックな素晴らしいパワーを見てください。私はおそらくこれを使用することはありませんが、それは知って良いです.... – Neil

+0

** + 1!**何が地獄か!エピック。 – ClosureCowboy

関連する問題