【问题标题】:How to check whether an object has certain method/property?如何检查对象是否具有某些方法/属性?
【发布时间】:2011-07-04 02:56:40
【问题描述】:

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

【问题讨论】:

  • myDynamicObject 的类型是什么?是从DynamicObject派生的类吗?
  • 用动态关键字声明的东西

标签: c# .net methods reflection properties


【解决方案1】:

为了避免AmbiguousMatchException,我宁愿说

objectToCheck.GetType().GetMethods().Count(m => m.Name == method) > 0

【讨论】:

    【解决方案2】:

    这是一个老问题,但我刚刚碰到它。 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;
        }
    } 
    

    【讨论】:

      【解决方案3】:

      最好不要为此使用任何动态类型,让你的类实现一个接口。 然后,您可以在运行时检查对象是否实现了该接口,因此是否具有预期的方法(或属性)。

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

      我认为这是唯一正确的方法。

      您指的是鸭子类型,这在您已经知道对象具有方法但编译器无法检查的情况下很有用。 例如,这在 COM 互操作场景中很有用。 (查看this文章)

      例如,如果您想将鸭子类型与反射结合起来,那么我认为您错过了鸭子类型的目标。

      【讨论】:

      • 如果对象可以是.NET框架提供的对象,我不能声明它来实现什么?
      • 有什么问题?您可以检查“对象”是否是这样的对象,由 .NET 框架以相同的方式提供
      • 例如,您要检查对象中是否存在“添加”方法。并且该对象可以是 List 或其他一些不是 IEnumerable 的类
      • 也许您应该看看使用 COM 编写 Adob​​e 产品的脚本。同一个函数调用可以返回完全不同的 COM 对象,根据(Adobe)的设计,它们唯一的共同祖先是对象。另外:这在几乎任何现代动态脚本语言(Python、Javascript、VB 脚本、PHP、Lua ......我可以继续下去)中都是一种常见的模式。这不是错误,而是一项功能。
      • 这是一种气味,但它是由微软创造的。查看 Button、LinkBut​​ton 等 WebControl。它们都实现了 OnClientClick 属性,但 ListControl 和 Panel 没有。 OnClientClick 未在接口中定义,因此反射是唯一的选择。
      【解决方案4】:

      你可以这样写:

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

      编辑:你甚至可以做一个扩展方法并像这样使用它

      myObject.HasMethod("SomeMethod");
      

      【讨论】:

      • GetType() 会返回运行时类型吗? (即不反对?)
      • 是的,GetType() 返回运行类型,而 typeof() 将返回对象。
      • 根据文档 GetType() 将返回“当前实例的确切运行时类型”。
      • 另外,扩展方法需要是静态的。
      • 我更喜欢这样写:objectToCheck.GetType().GetMethod(methodName) != null
      【解决方案5】:

      通过反射

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

      类似的方法

      【讨论】:

      • 不错。您还可以在循环中执行 GetMethod 以获取适当的定义属性。
      • 对于循环访问 UI 控件及其父项的链接列表很有用
      • GetType() 中有类似GetProperties() 的方法。它返回PropertyInfo 的数组。但是如何使用GetProperties() 方法呢?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-07
      • 1970-01-01
      • 2021-03-12
      相关资源
      最近更新 更多