Як перевірити, чи має об’єкт певний метод / властивість?


155

Можливо, використовуєте динамічну схему? Ви можете викликати будь-який метод / властивість, використовуючи динамічне ключове слово, правда? Як перевірити, чи існує метод, перш ніж викликати, наприклад, myDynamicObject.DoStuff ()?


Який тип myDynamicObject ? Це похідний клас DynamicObject?
Чен Чен

щось оголошено динамічним ключовим словом
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 () поверне тип виконання? (тобто не об’єкт?)
Луї Ріс

2
так, GetType () повертає запущений тип, тоді як typeof () повертає об'єкт.
Жульєн

1
Згідно з документами GetType () поверне "Точний тип часу виконання поточного екземпляра".
tzup

Також метод розширення повинен бути статичним.
Фрейзер

9
Я вважаю за краще писати: objectToCheck.GetType (). GetMethod (methodName)! = Null
efirat

85

через рефлексію

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

Аналогічно і для методів


Приємно. Ви також можете зробити GetMethod в циклі, щоб отримати відповідне визначене властивість.
Інь

Корисно для перегляду циклу пов'язаних списків елементів керування користувальницьким інтерфейсом та їх батьків
Chicowitz

У GetType()є такий метод, як GetProperties(). Це повертається масив PropertyInfo. Але як я можу використовувати GetProperties()метод?
Йогеш Патель

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 Framework, і я не можу оголосити його для чого-небудь реалізовувати?
Луї Різ

В чому проблема ? Ви можете перевірити, чи є "об'єкт" таким об'єктом, що надається .NET рамкою точно так само
Frederik Gheysels

наприклад, ви хочете перевірити, чи є в об’єкті метод "Додати". І об'єктом може бути Список <int> або інший клас, який не є IEnumerable
Louis Rhys

3
Можливо, вам слід поглянути на те, як створити сценарій продукту Adobe з COM. Один і той же виклик функції може повертати абсолютно різні об'єкти COM, і за (дизайном Adobe) єдиним спільним предком є ​​об'єкт. Також: це звичайна модель у будь-якій сучасній мові динамічного сценарію (Python, Javascript, VB скрипт, PHP, Lua ... я можу продовжувати і продовжувати). Це не помилка, це особливість.
Тім Кітінг

5
Це запах, але його створив microsoft. Подивіться на WebControls, такі як Button, LinkButton тощо. Вони обидва реалізують властивість OnClientClick, але, скажімо, ListControl і Panel цього не роблять. OnClientClick не визначений в інтерфейсі, тому відображення - єдиний варіант.
HammerIp
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.