代码之家  ›  专栏  ›  技术社区  ›  R. Martinho Fernandes

是否有一个C相当于Ruby的“回应”?`?

  •  7
  • R. Martinho Fernandes  · 技术社区  · 15 年前

    我在给“鸭”写一个简单的包装纸 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);
        }
    }
    

    如果 动态 对象可以响应 Bar 签名。但如果不行的话,这只会在我打电话的时候失败。 酒吧 . 我希望它能更快地失败,也就是说,在构造 DuckFoo 包装器。像这样:

    public DuckFoo(dynamic duck)
    {
        if(/* duck has no matching Bar method */)
            throw new ArgumentException("duck", "Bad dynamic object");
        this.duck = duck;
    }
    

    红宝石中有一个 respond_to? 可用于测试对象是否“具有”某个方法的方法。有没有一种方法可以用C 4中的动态对象来测试它?

    (我知道,即使有了这个检查,酒吧调用也可能在以后失败,因为 duck 让它稍后停止对方法的响应。)

    3 回复  |  直到 15 年前
        1
  •  4
  •   Community CDub    7 年前

    您可以在构建时使用反射检查被包装对象上可用的方法。

    只要打电话 Type.GetMethods() 在接口和要传入的类型上,并确保存在适当的方法。


    编辑:

    正如建议的那样 itowlson 还有一个处理动态类型的选项。如果检查传递的对象上是否存在IDynamicMetabObjectProvider接口,则可以调用 IDynamicMetaObjectProvider.GetMetaObject() . GetDynamicMemberNames() ,并使用此信息。

    如果接口不存在,则可以只还原为type.getMethods()。

    这也应该处理“动态”类型。

        2
  •  1
  •   Maximilian Mayerl    15 年前

    我不知道有什么确切的方法来检查对象是否提供了一种特定的方法。当然,您可以使用反射,但只有当对象是.NET对象时,反射才有效。如果您确定它是,那么,正如前面所说,没有问题,只需对对象调用getType()并使用getMethod()进行检查。

    另一方面,正如您自己所说的,即使此时的检查也不能保证对方法的调用在稍后会成功,所以我认为检查是无用的。让电话在实际通话时失败。也可能是您的检查显示对象没有提供特定的方法,但稍后,当您实际调用它时,它会提供。

        3
  •  0
  •   Jon Benedicto    15 年前

    使用反射检查方法:

    if (duck.GetType().GetMethod("Bar") == null) {
        throw new ArgumentException("duck", "Bad dynamic object");
    }