我正在编写一个简单的包装器,以便针对已知接口“绑定”dynamic
对象:
interface IFoo { string Bar(int fred); }
class DuckFoo : IFoo
{
private readonly dynamic duck;
public DuckFoo(dynamic duck)
{
this.duck = duck;
}
public string Bar(int fred)
{
return duck.Bar(fred);
}
}
如果dynamic
对象可以响应Bar
签名,则此方法可以正常工作。但是,如果它不能只在我呼叫Bar
时失败。我希望它能否更快地失败,即在构造DuckFoo
包装器时使用参数验证。像这样:
public DuckFoo(dynamic duck)
{
if(/* duck has no matching Bar method */)
throw new ArgumentException("duck", "Bad dynamic object");
this.duck = duck;
}
在Ruby中,有一个respond_to?
方法可用于测试对象是否“具有”某种方法。有没有办法用C#4中的动态对象测试它?
(我知道即使使用此检查,Bar调用也可能在以后失败,因为duck
的动态特性使其稍后停止响应方法。)
答案 0 :(得分:4)
您可以在施工时检查使用Reflection包裹的对象上的可用方法。
只需在界面上调用Type.GetMethods()和传入的类型,并确保存在适当的方法。
编辑:
正如itowlson所建议的,还有一个处理动态类型的选项。如果检查传递的对象上是否存在IDynamicMetaObjectProvider接口,则可以调用IDynamicMetaObjectProvider.GetMetaObject()。GetDynamicMemberNames(),并使用此信息。
如果界面不存在,您可以恢复为Type.GetMethods()。
这也应该处理“动态”类型。
答案 1 :(得分:1)
我不知道检查对象是否提供特定方法的确切方法。当然,您可以使用反射,但只有在对象是.NET对象时才有效。如果你确定它不是,如上所述,没问题,只需在对象上调用GetType()并使用GetMethod()进行检查。
另一方面,正如你自己所说,即使是在这一点检查也不能保证对方法的调用将在以后成功,所以我认为检查是没用的。只是让呼叫在实际发生时失败。也可能是你的检查表明对象没有提供特定的方法,但是稍后,当你真正调用它时,它确实会这样做。
答案 2 :(得分:0)
使用反射来检查方法:
if (duck.GetType().GetMethod("Bar") == null) {
throw new ArgumentException("duck", "Bad dynamic object");
}