【问题标题】:Interface detection reflection界面检测反射
【发布时间】:2014-02-26 03:39:23
【问题描述】:

我的 C# 模块中有这段代码:

if (customer is IBuyer) { customer.WaiveServiceFee(); }

只要 customer 是一个实现了 IBuyer 的对象,就可以很好地编译。但是使用条件的整个想法是测试客户对象是否实现了 IBuyer。如果没有,我会收到一个编译时错误,即客户不包含 WaiveServiceFee 的定义(WaiveServiceFee 是由 IBuyer 实现产生的方法——它当然不是客户类的一部分)。

我对 C# 不够熟悉,不知道如何应用上述逻辑在运行时调用 WaiveServiceFee 并使程序可编译?

谢谢。

【问题讨论】:

    标签: c# reflection interface


    【解决方案1】:

    改用as operator

    var buyer = customer as IBuyer;
    if(buyer != null)
        buyer.WaiveServiceFee();
    

    如果customer没有实现IBuyer,那么buyer将为null。您可以轻松检查该值是否为null,如果它不为null,则调用您的方法。在分配@987654328之后@ 在编译时将被视为IBuyer,因此您将能够调用您的方法而不会出现 compile-time 错误。

    【讨论】:

    • 考虑将临时变量命名为buyer,而不是混淆的缩写cust
    • @EricLippert 已更改 :)
    【解决方案2】:

    Selman22 的解决方案是正确的。另一种解决方案是插入演员表:

    if (customer is IBuyer)
        ((IBuyer)customer).WaiveServiceFee();
    

    然而,一些程序员认为这有些不雅。两者都可以工作,并且在生产代码中很常见。

    【讨论】:

    • 我曾经认为这很不雅。但是我现在经常使用它,发现代码非常干净。如果您不确定您的对象是否实现了接口,那么您的程序中有一个真正的决策点。
    • 我也喜欢这种方法,实际上我觉得它比上面公认的答案更“优雅”。但是,我不熟悉 As 关键字。
    • 我刚刚意识到这里的一个优点是您不需要创建新变量。这可能会吸引一些读者。
    • 但是如果您使用 MS 静态代码分析器(例如 FxCop),您将收到性能警告 CA1800: Do not cast unnecessarily,因为您的代码执行重复转换以键入 'IBuyer' 并且此类转换会稍微降低性能。
    • @IgorKustov:尽管确实很少有程序的惊人性能可以归功于避免不必要的类型检查。
    猜你喜欢
    • 1970-01-01
    • 2012-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-25
    相关资源
    最近更新 更多