C# 接口(interface)。不指定派生类名

标签 c# interface

是否可以在派生类中运行一个方法而不让基类知道它的名字。 IE:找出谁实现了 ITest 并运行他们在该类中指定的方法。

我知道的奇怪问题。

class BaseClass
{

    public static void Main (string[] args)
    {
        ITest f; //Null here. Want this to auto magically look for classes implementing ITest.  
        f.Run (); //And then run this. #NoReflection #NoBlackMagic. 
    }
}

public interface ITest //This will live in the same file as BaseClass
{
    void Run ();
}


class Derrived : ITest //Lives in another file
{
    #region ITest implementation

    public void Run ()
    {
        Console.WriteLine ("Test was run");
    }

    #endregion
} 

想法是。可以说 BaseClass 本身就是一个用户 GUI,而 Derived 类位于另一个文件中的某个地方。

给某人 Base GUI 类而不用他/她担心硬编码的 ITest f = new Derived() 类会很棒。

如果有更多的类实现 ITest,如果它们都是 Run() 就好了;

我已经看到了一些很酷的多态性技巧,但您仍然需要定义类名。

也许我错过了接口(interface)的要点:(

干杯橡树。

最佳答案

反射(reflection)将是做到这一点的方法。

您可以通过枚举程序集中的所有类来识别实现ITest 的类:

var assembly = Assembly.GetExecutingAssembly();
var itestTypes = assembly.GetTypes().Where (t => t.IsClass &&
                                            typeof(ITest).IsAssignableFrom(t));
foreach (var t in itestTypes)
{
    Console.WriteLine (t.ToString());
    ITest test = (ITest)Activator.CreateInstance(t);
    test.Run();
}

依赖注入(inject)

实现此目的的另一种方法是使用依赖注入(inject)框架,例如 Unity .它仍在底层使用反射。

示例:在某个时候你会注册你想使用的类:

public static void RegisterClasses(IUnityContainer container)
{
    container.RegisterType<ITest, Derived>();
}

这表示“当需要 ITest 时,创建一个 Derived 的实例”。

您的代码可能如下所示:

ITest f = container.Resolve<ITest>();
f.Run();

容器将查看其注册并选择生成Derived

其他选项是这样的:

public class BaseClass
{
    private ITest _test;

    public BaseClass(ITest test) //injected, no knowledge of IUnityContainer required
    {
       _test = test;
    }
}

//elsewhere:
container.Resolve<BaseClass>();

或者使用 DependencyAttribute :

public class BaseClass
{
    [Dependency]
    public ITest Test {get; set;}
}

//elsewhere:
container.Resolve<BaseClass>();

好处是它不需要无参数构造函数,不像第一位代码,它将以相同的方式“解析”所有参数以创建 Derived

关于C# 接口(interface)。不指定派生类名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28339575/

相关文章:

c# - 如何检测 Windows 登录事件?

c# - 在通用抽象类中实现强制转换运算符

java - 接口(interface)编程

java - 抽象类或接口(interface)

java - 为什么我得到预期的类、枚举和接口(interface)?

objective-c - Objective C - 如何创建接口(interface)?

c# - 从哪里获取通过 API 访问 Azure ServiceBus 所需的信息,尤其是 ClientID 和 ClientSecret

c# - 为另一个程序包装代码/类

c# - 编码普通结构 : does C# copy them onto heap?

c# - 您如何平衡框架/API 设计和 TDD