如何检查对象是否具有某种方法/属性?


155

也许使用动态模式?您可以使用dynamic关键字调用任何方法/属性,对吗?例如,如何在调用myDynamicObject.DoStuff()之前检查该方法是否存在?


myDynamicObject的类型是什么?它是从中派生的类DynamicObject吗?
Cheng Chen

用动态关键字声明的内容
Louis Rhys

Answers:


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()将返回对象。
Julien

1
根据文档,GetType()将返回“当前实例的确切运行时类型”。
tzup

同样,扩展方法将需要是静态的。
弗雷泽

9
我更喜欢这样写:objectToCheck.GetType()。GetMethod(methodName)!= null
efirat 2012年

85

通过反射

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

方法也相似


真好 您也可以循环执行GetMethod以获取适当的已定义属性。
Jnr

对于循环浏览UI控件及
其父级的

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框架提供的“对象”是否就是这样的对象
Frederik Gheysels 2011年

例如,您要检查对象中是否有“添加”方法。对象可以是List <int>或不是IEnumerable的其他某些类
Louis Rhys

3
也许您应该看看如何使用COM编写Adobe产品脚本。相同的函数调用可以返回完全不同的COM对象,根据Adobe的设计,它们唯一的共同祖先是object。另外:在几乎所有现代动态脚本语言(Python,Javascript,VB脚本,PHP,Lua ...我可以继续)中,这都是司空见惯的模式。这不是一个错误,这是一个功能。
Tim Keating

5
这是一种气味,但它是由Microsoft创建的。查看诸如Button,LinkBut​​ton等的WebControl。它们都实现OnClientClick属性,但ListControl和Panel却没有。接口中未定义OnClientClick,因此反射是唯一的选择。
HammerIp 2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.