Skip to main content
 首页 » 编程设计

dynamic之使用C#4对动态对象进行鸭子类型(duck typing)测试

2024年09月07日26over140

我想在C#中使用动态对象编写一个简单的鸭子输入示例。在我看来,动态对象应该具有HasValue / HasProperty / HasMethod方法,该方法具有单个字符串参数,用于表示您要尝试对其进行操作的值,属性或方法的名称。我正在尝试避免try / catch块,并在可能的情况下进行更深入的思考。这似乎是在动态语言(JS,Ruby,Python等)中进行鸭子键入的一种常见做法,即在尝试使用属性/方法之前先对其进行测试,然后返回默认值或引发受控异常。下面的示例基本上是我想要完成的。

如果上述方法不存在,那么有人可以为动态预先创建扩展方法吗?

示例:在JavaScript中,我可以相当容易地测试对象上的方法。

//JavaScript 
function quack(duck) { 
  if (duck && typeof duck.quack === "function") { 
    return duck.quack(); 
  } 
  return null; //nothing to return, not a duck 
}

我将如何在C#中执行相同的操作?
//C# 4 
dynamic Quack(dynamic duck) 
{ 
  //how do I test that the duck is not null,  
  //and has a quack method? 
 
  //if it doesn't quack, return null 
}

请您参考如下方法:

尝试这个:

    using System.Linq; 
    using System.Reflection; 
    //... 
    public dynamic Quack(dynamic duck, int i) 
    { 
        Object obj = duck as Object; 
 
        if (duck != null) 
        { 
            //check if object has method Quack() 
            MethodInfo method = obj.GetType().GetMethods(). 
                            FirstOrDefault(x => x.Name == "Quack"); 
 
            //if yes 
            if (method != null) 
            { 
 
                //invoke and return value 
                return method.Invoke((object)duck, null); 
            } 
        } 
 
        return null; 
    } 

或此(仅使用动态):
    public static dynamic Quack(dynamic duck) 
    { 
        try 
        { 
            //invoke and return value 
            return duck.Quack(); 
        } 
        //thrown if method call failed 
        catch (RuntimeBinderException) 
        { 
            return null; 
        }         
    }