是否可以在派生类中运行一个方法而不让基类知道它的名字。 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/