Bagaimana cara memeriksa apakah suatu objek memiliki metode / properti tertentu?

155

Mungkin menggunakan pola dinamis? Anda dapat memanggil metode / properti apa pun menggunakan kata kunci dinamis, bukan? Bagaimana memeriksa apakah metode tersebut ada sebelum memanggil myDynamicObject.DoStuff (), misalnya?

Louis Rhys
sumber
Apa jenis myDynamicObject ? Apakah kelas ini berasal DynamicObject?
Cheng Chen
sesuatu yang dinyatakan dengan kata kunci dinamis
Louis Rhys

Jawaban:

224

Anda dapat menulis sesuatu seperti itu:

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

Sunting: Anda bahkan dapat melakukan metode ekstensi dan menggunakannya seperti ini

myObject.HasMethod("SomeMethod");
Julien
sumber
GetType () akan mengembalikan tipe runtime? (Yaitu tidak keberatan?)
Louis Rhys
2
ya, GetType () mengembalikan tipe berjalan sedangkan typeof () akan mengembalikan objek.
Julien
1
Menurut dokumen GetType () akan mengembalikan "Jenis runtime yang tepat dari instance saat ini".
tzup
Juga, metode ekstensi harus statis.
Fraser
9
Saya lebih suka menulis: objectToCheck.GetType (). GetMethod (methodName)! = Null
efirat
85

melalui Refleksi

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

Serupa untuk metode

Stecya
sumber
Bagus. Anda juga bisa melakukan GetMethod dalam satu lingkaran untuk mendapatkan properti yang ditentukan sesuai.
Jnr
Berguna untuk mengulang daftar kontrol UI yang terhubung dan Orang Tua mereka
Chicowitz
Di GetType()sana ada metode like GetProperties(). Ini mengembalikan array PropertyInfo. Tetapi bagaimana saya bisa menggunakan GetProperties()metode?
Yogesh Patel
43

Itu adalah pertanyaan lama, tetapi saya hanya menabraknya. Type.GetMethod(string name)akan melempar AmbiguousMatchException jika ada lebih dari satu metode dengan nama itu, jadi kami lebih baik menangani kasus itu

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;
    }
} 
esskar
sumber
18

Bukankah lebih baik tidak menggunakan tipe dinamis apa pun untuk ini, dan biarkan kelas Anda mengimplementasikan antarmuka. Kemudian, Anda dapat memeriksa pada saat runtime apakah suatu objek mengimplementasikan antarmuka itu, dan dengan demikian, memiliki metode yang diharapkan (atau properti).

public interface IMyInterface
{
   void Somemethod();
}


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

Saya pikir ini adalah satu-satunya cara yang benar.

Hal yang Anda maksud adalah bebek-mengetik, yang berguna dalam skenario di mana Anda sudah tahu bahwa objek memiliki metode, tetapi kompilator tidak dapat memeriksa itu. Ini berguna dalam skenario interop COM misalnya. (periksa artikel ini )

Jika Anda ingin menggabungkan bebek-mengetik dengan refleksi misalnya, maka saya pikir Anda kehilangan tujuan mengetik bebek.

Frederik Gheysels
sumber
2
bagaimana jika objek tersebut dapat menjadi objek yang disediakan oleh .NET framework, dan saya tidak dapat mendeklarasikannya untuk mengimplementasikan apa pun?
Louis Rhys
Apa masalahnya ? Anda dapat memeriksa apakah 'objek' adalah objek seperti itu, yang disediakan oleh .NET framework dengan cara yang sama
Frederik Gheysels
misalnya, Anda ingin memeriksa apakah ada metode "Tambah" di objek. Dan objek dapat berupa Daftar <int>, atau kelas lain yang bukan merupakan IEnumerable
Louis Rhys
3
Mungkin Anda harus melihat skrip produk Adobe dengan COM. Panggilan fungsi yang sama dapat mengembalikan objek COM yang sama sekali berbeda, dan dengan desain (Adobe), satu-satunya nenek moyang mereka adalah objek. Juga: ini adalah pola umum di hampir semua bahasa skrip dinamis modern (Python, Javascript, skrip VB, PHP, Lua ... Saya bisa terus dan terus). Ini bukan bug, ini fitur.
Tim Keating
5
Ini bau tetapi itu diciptakan oleh microsoft. Lihatlah WebControls seperti Button, LinkButton, dll. Keduanya mengimplementasikan properti OnClientClick tetapi, katakanlah, ListControl dan Panel tidak. OnClientClick tidak didefinisikan dalam antarmuka sehingga refleksi adalah satu-satunya pilihan.
HammerIp