2009-12-09 27 views
7

私は単純なラッパーを書いて知られているインタフェースに対して「鴨」dynamicオブジェクトへ:Rubyの `respond_to?`に相当するC#はありますか?

interface IFoo { string Bar(int fred); } 

class DuckFoo : IFoo 
{ 
    private readonly dynamic duck; 

    public DuckFoo(dynamic duck) 
    { 
     this.duck = duck; 
    } 

    public string Bar(int fred) 
    { 
     return duck.Bar(fred); 
    } 
} 

dynamicオブジェクトはBar署名に対応できる場合、これは正常に動作します。しかし、それができない場合は、私がBarと呼ぶときだけ失敗します。私はそれが速く、すなわち、DuckFooラッパーの構築時に引数の検証で失敗する可能性がある場合、私は好きです。このようなものは:Rubyで

public DuckFoo(dynamic duck) 
{ 
    if(/* duck has no matching Bar method */) 
     throw new ArgumentException("duck", "Bad dynamic object"); 
    this.duck = duck; 
} 

オブジェクトが特定のメソッド「を有する」かどうかをテストするために使用することができるrespond_to?方法があります。 C#4の動的オブジェクトでそれをテストする方法はありますか?

(私はduckの動的な性質は、それが後でメソッドへの応答を停止することができますので、これでもして後で失敗する可能性がバーの呼び出しを確認することを認識しています。)あなたがオブジェクトで利用できるメソッドをチェックすることができ

答えて

4

建設時にReflectionを使用してラップされています。

インターフェイス上でType.GetMethods()と渡される型を呼び出すだけで、適切なメソッドが存在することを確認してください。


編集:

itowlsonによって示唆されるように

は、同様に、ダイナミックタイプを処理するためのオプションがあります。渡されたオブジェクトのIDynamicMetaObjectProviderインターフェイスの存在を確認すると、IDynamicMetaObjectProvider.GetMetaObject()を呼び出すことができます。 GetDynamicMemberNames()を入力し、この情報を使用してください。

インターフェイスが存在しない場合は、単にType.GetMethods()に戻すことができます。

"ダイナミック"タイプも処理する必要があります。方法を確認する

+0

「duck」が「ダイナミックダック」として宣言されている場合、 'duck.GetType()'を実行するとどうなりますか?それはどんなタイプのものですか? – dtb

+0

動的オブジェクトが.NETオブジェクトの場合は、オブジェクトのタイプが取得されます。 –

+0

私はあなたが動的オブジェクト上のようなリフレクションを行うことはできないと思います...もしそれらが通常のCLRオブジェクトであれば可能ですが、例えばIronRubyからのオブジェクトではできません。 –

0

使用反射:

if (duck.GetType().GetMethod("Bar") == null) { 
    throw new ArgumentException("duck", "Bad dynamic object"); 
} 
+1

正常に動作しますが、通常のCLRオブジェクトでのみ動作します。本当に動的なオブジェクトはBarメソッドを持たず、依然として呼び出しに応答します。 –

1

オブジェクトが特定のメソッドを提供する場合、私はチェックする明確な方法を知っていません。もちろん、リフレクションを使用することはできますが、オブジェクトが.NETオブジェクトの場合にのみ動作します。すでに述べたように、それが問題ではないと確信できる場合は、オブジェクトのGetType()を呼び出し、GetMethod()でチェックしてください。

一方、自分で言ったように、現時点でのチェックでも、メソッドの呼び出しが後で成功するとは思わないので、チェックは役に立たないと思います。実際にコールが失敗した場合は、そのコールを失敗させてください。また、オブジェクトが特定のメソッドを提供していないが、後で、実際にそれを呼び出すときにチェックが行われることもあります。

関連する問題