オブジェクトに特定のメソッド/プロパティがあるかどうかを確認するにはどうすればよいですか?


155

おそらく動的パターンを使用していますか?動的キーワードを使用して、任意のメソッド/プロパティを呼び出すことができますよね?たとえば、myDynamicObject.DoStuff()を呼び出す前にメソッドが存在するかどうかを確認する方法は?


myDynamicObjectのタイプはですか?派生クラスDynamicObjectですか?
チェンチェン

dynamicキーワードで宣言されたもの
Louis Rhys

回答:


224

あなたはそのようなものを書くことができます:

public static bool HasMethod(this object objectToCheck, string methodName)
{
    var type = objectToCheck.GetType();
    return type.GetMethod(methodName) != null;
} 

編集:拡張メソッドを実行して、このように使用することもできます

myObject.HasMethod("SomeMethod");

GetType()はランタイムタイプを返しますか?(つまり、異議ありませんか?)
Louis Rhys

2
はい、GetType()は実行中のタイプを返しますが、typeof()はオブジェクトを返します。
ジュリアン

1
ドキュメントによると、GetType()は「現在のインスタンスの正確なランタイムタイプ」を返します。
tzup

また、拡張メソッドは静的である必要があります。
Fraser

9
私は書くことを好む:objectToCheck.GetType()。GetMethod(methodName)!= null
efirat

85

リフレクション経由

 var property = object.GetType().GetProperty("YourProperty")
 property.SetValue(object,some_value,null);

メソッドについても同様です


いいね。GetMethodをループで実行して、適切な定義済みプロパティを取得することもできます。
Jnr '25年

UIコントロールのリンクリストとその親をループのための有用な
Chicowitz

GetType()ような方法がありGetProperties()ます。の配列を返していPropertyInfoます。しかし、どうすればGetProperties()メソッドを使用できますか?
Yogesh Patel

43

古い質問ですが、私はそれに遭遇しました。 Type.GetMethod(string name)その名前のメソッドが複数ある場合、AmbiguousMatchExceptionをスローするので、そのケースをより適切に処理します

public static bool HasMethod(this object objectToCheck, string methodName)
{
    try
    {
        var type = objectToCheck.GetType();
        return type.GetMethod(methodName) != null;
    }
    catch(AmbiguousMatchException)
    {
        // ambiguous means there is more than one result,
        // which means: a method with that name does exist
        return true;
    }
} 

18

これには動的型を使用せず、クラスにインターフェイスを実装させるほうが良いでしょう。次に、実行時にオブジェクトがそのインターフェースを実装しているかどうか、つまり、期待されるメソッド(またはプロパティ)があるかどうかを確認できます。

public interface IMyInterface
{
   void Somemethod();
}


IMyInterface x = anyObject as IMyInterface;
if( x != null )
{
   x.Somemethod();
}

これが唯一の正しい方法だと思います。

あなたが参照しているのはダックタイピングです。これは、オブジェクトにメソッドがあることがすでにわかっているが、コンパイラーがそれをチェックできないシナリオで役立ちます。これは、たとえば、COM相互運用シナリオで役立ちます。(この記事を確認しください)

たとえば、アヒルのタイピングとリフレクションを組み合わせたい場合は、アヒルのタイピングの目標を見逃していると思います。


2
オブジェクトが.NETフレームワークによって提供されるオブジェクトであり、何かを実装するように宣言できない場合はどうなりますか?
Louis Rhys

どうしたの ?あなたは、「オブジェクトが」ちょうど同じように、.NETフレームワークによって提供されるこのようなオブジェクトであるかどうかを確認することができます
フレデリックGheysels

たとえば、オブジェクトに「追加」メソッドがあるかどうかを確認するとします。オブジェクトはList <int>、またはIEnumerableではないその他のクラスにすることができます
Louis Rhys

3
おそらく、COMを使用したアドビ製品のスクリプト作成を確認する必要があります。同じ関数呼び出しで完全に異なるCOMオブジェクトを返すことができ、(Adobeの)設計により、それらの共通の祖先はオブジェクトのみです。また、これは、ほとんどすべての最新の動的スクリプト言語(Python、Javascript、VBスクリプト、PHP、Lua ...で継続できます)のありふれたパターンです。これはバグではなく、機能です。
Tim Keating

5
それはにおいですが、マイクロソフトによって作成されました。Button、LinkBut​​tonなどのWebControlを見てください。どちらもOnClientClickプロパティを実装していますが、たとえば、ListControlとPanelは実装していません。OnClientClickはインターフェイスで定義されていないため、リフレクションが唯一のオプションです。
HammerIp 2012年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.