【问题标题】:How to define the default implementation of an interface in c#?如何在 C# 中定义接口的默认实现?
【发布时间】:2011-03-17 07:40:45
【问题描述】:

c#中有一些黑魔法代码,您可以在其中定义接口的默认实现。

所以你可以写

var instance = new ISomeInterface();

任何指针?

更新 1:请注意,我没有问这是否是个好主意。怎么可能做到。

更新 2:任何看到已接受答案的人。

  • “这应该仅仅被视为一种好奇心。”来自 Marc Gravel "Newing up" Interfaces
  • “使用专为 COM 互操作设计的工具来做完全不同的事情是个坏主意。这会使下一个必须维护它的人无法理解你的代码”来自 Eric Lippert "Newing up" Interfaces
  • “虽然它可能有效,但如果理性编码人员在生产代码中发现它,它将被重构为使用基类或依赖注入。”来自 Stephen Cleary 在下面的评论中。

【问题讨论】:

标签: .net inheritance interface


【解决方案1】:

黑魔法来了:

class Program
{
    static void Main()
    {
        IFoo foo = new IFoo("black magic");
        foo.Bar();
    }
}

[ComImport]
[Guid("C8AEBD72-8CAF-43B0-8507-FAB55C937E8A")]
[CoClass(typeof(FooImpl))]
public interface IFoo
{
    void Bar();
}

public class FooImpl : IFoo
{
    private readonly string _text;
    public FooImpl(string text)
    {
        _text = text;
    }

    public void Bar()
    {
        Console.WriteLine(_text);
    }
}

请注意,您不仅可以实例化接口,还可以将参数传递给它的构造函数:-)

【讨论】:

  • @Simon,我建议您将 RSS 阅读器调整为这两个博客 :-)
  • @Daren 已经有了。但是我所有的“接口默认实现”组合都一无所获。信噪比不好:)
  • @daren 有点有趣,在您发布答案后,“不可能”的答案得到了支持。
  • 如果我在同事的代码中看到这个,我会解雇他们。
【解决方案2】:

仅当 ISomeInterface 是一个类时。

更新(澄清):

Jon Skeet 有a talk,他提到了接口的默认实现。但是,它们不是 C# 语言的一部分。演讲是关于 Jon Skeet希望在 C# 的未来版本中看到什么。

目前,唯一的默认实现是通过(可能是abstract)基类完成的。

【讨论】:

  • 我对所有不正确的答案投了反对票。因为他们不正确。没有任何合理性。见达林斯回答
  • 我看到了“正确”的答案。虽然它可能有效,但如果理性编码人员在生产代码中发现它,它将被重构为使用基类或依赖注入。
  • @Setphen 同意。编辑了这个问题,希望没有人认为这是个好主意。
【解决方案3】:

也许你指的是依赖注入?在使用 DI 框架(如Ninject 或 Unity)时,您可以为每个接口定义默认实例,然后像这样使用它:

(假设你有IWeapon 接口并且Sword 实现了它)

IKernel kernel = new StandardKernel();
kernel.Bind<IWeapon>().To<Sword>();
var weapon = kernel.Get<IWeapon>();

但是 Ninject(和大多数其他 IoC 框架)可以做一些更聪明的事情,例如:假设我们有一个类 Warrior,它在其构造函数中将 IWeapon 作为参数。我们可以从 Ninject 获取Warrior 的实例:

var warrior = kernel.Get<Warrior>();

Ninject 会将我们指定的 IWeapon 实现传递给Warrior 构造函数方法并返回新实例。

除此之外,我不知道任何允许这种行为的语言功能。

【讨论】:

  • 好建议,但不是我想要的。见达林斯回答
  • 是的,我错过了您在问题中提到“黑魔法”的部分 :-) 感谢您提出这个问题——我学到了一些新东西!
猜你喜欢
  • 2022-12-17
  • 1970-01-01
  • 2015-07-31
  • 2014-10-01
  • 2016-06-29
  • 2014-12-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多