代码之家  ›  专栏  ›  技术社区  ›  Wim Coenen

在C语言中实现安全鸭式键入#

  •  17
  • Wim Coenen  · 技术社区  · 15 年前

    看看如何 Go 处理界面并喜欢它,我开始思考如何在C中实现类似的duck输入,如下所示:

    var mallard = new Mallard(); // doesn't implement IDuck but has the right methods
    IDuck duck = DuckTyper.Adapt<Mallard,IDuck>(mallard);
    

    这个 DuckTyper.Adapt 方法将使用 System.Reflection.Emit 在运行中构建适配器。也许有人已经写了这样的东西。我想这和模拟框架已经做的没什么不同。

    但是,如果 Mallard 实际上没有权利 IDuck 方法。为了在编译时更早地得到错误,我必须编写一个 MallardToDuckAdapter 这正是我想要避免的。

    有更好的方法吗?

    编辑 :显然,我所说的“安全鸭式打字”的恰当术语是 structural typing .

    4 回复  |  直到 15 年前
        1
  •  13
  •   dtb    15 年前

    如果你面前没有一头活生生的、能呼吸的母牛,你怎么能知道一头牛走路像鸭子,咯咯叫像鸭子?

    duck类型是运行时使用的一个概念。编译时的一个类似概念是 structural typing 这是CLR不支持的afaik。(CLR围绕 nominative typing )

    [结构类型系统]与指定系统形成对比,其中比较基于显式声明或类型名称,而duck类型,其中只检查运行时访问的结构部分的兼容性。

    确保duck类型在运行时不会抛出异常的通常方法是单元测试。

        2
  •  5
  •   Bob    15 年前

    DuckTyping for C#

    reflection.emit用于发出直接调用原始对象的IL。

    我不认为这个库会给你编译时出错的想法,我不确定这是否完全可行。使用单元测试来帮助补偿这一点。

        3
  •  1
  •   Joseph    15 年前

    我认为没有另一种方法可以让您获得编译时错误。

    然而,这是单元测试非常适合做的事情。您将编写一个单元测试来验证

    DuckTyper.Adapt<Mallard, IDuck>(mallard);
    

    成功映射。

        4
  •  1
  •   Konrad Rudolph    15 年前

    我知道隐式接口(即go接口)是为vb 10设计的(不知道C)。不幸的是,它们在发布之前就被废弃了(我认为它们甚至没有进入beta)。很高兴看到他们是否会出现在.NET的未来版本中。

    当然,新的 dynamic 类型可以用来实现很多相同的功能,但这仍然不是相同的“隐式接口”仍然允许强类型化,我认为这很重要。