How to define the default implementation of an interface in c#?

情到浓时终转凉″ 提交于 2019-12-14 00:15:03

问题


There is some black magic code in c# where you can define the default implementation of an interface.

So you can write

var instance = new ISomeInterface();

Any pointers?

UPDATE 1: Note that I did not ask if this is a good idea. Just how was it possible to do it.

UPDATE 2: to anyone seeing the accepted answer.

  • "this should be treated merely as a curiosity." from Marc Gravel "Newing up" Interfaces
  • "It's a bad idea to use a tool designed for COM interop to do something completely and utterly different. That makes your code impossible to understand for the next guy who has to maintain it" from Eric Lippert "Newing up" Interfaces
  • "While it may work, if it were ever found in production code by a rational coder, it would be refactored to use a base class or dependency injection instead." from Stephen Cleary in a comment below.

回答1:


Here comes the black magic:

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);
    }
}

Notice that not only you can instantiate an interface but also pass arguments to its constructor :-)




回答2:


Only if ISomeInterface is a class.

Update (for clarification):

Jon Skeet has a talk where he mentions default implementations for interfaces. They are not part of the C# language, though. The talk is about what Jon Skeet would like to see in a future version of C#.

For now, the only default implementations are done via (possibly abstract) base classes.




回答3:


Maybe you refer to Dependency Injection? Where when using DI framework (such as Ninject or Unity), you can define default instance for each interface and then using it like this:

(assuming you have IWeapon interface and Sword implements it)

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

But Ninject (and most other IoC frameworks) can do some more clever things, like: let's say we have the class Warrior that takes IWeapon as a parameter in its constructor. We can get an instance of Warrior from Ninject:

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

Ninject will pass the IWeapon implementation we specified to the Warrior constructor method and return the new instance.

Other than that, I don't know of any in-language feature that allows this kind of behavior.



来源:https://stackoverflow.com/questions/3271223/how-to-define-the-default-implementation-of-an-interface-in-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!