我正在制作一个小项目,我正在试图弄清楚是否有可能获得从特定接口继承的每个类的实例。
以下是我正在努力完成的一个简化示例:
public interface IExample
{
string Foo();
}
public class Example1 : IExample
{
public string Foo()
{
return "I came from Example1 !";
}
}
public class Example2 : IExample
{
public string Foo()
{
return "I came from Example2 !";
}
}
//Many more ExampleN's go here
public class ExampleProgram
{
public static void Main(string[] args)
{
var examples = GetExamples();
foreach (var example in examples)
{
Console.WriteLine(example.Foo());
}
}
public static List<IExample> GetExamples()
{
//What goes here?
}
}
GetExamples方法是否有任何方法(没有硬编码)返回包含从接口IExample继承的每个类的实例的列表?您可以给予任何见解。非常感谢。
答案 0 :(得分:2)
请参阅:Check if a class is derived from a generic class
另外:Implementations of interface through Reflection(这可能正是您想要的)
您基本上只需要枚举目标程序集中的每个类型并测试它是否实现了接口。
答案 1 :(得分:1)
在Matt的解决方案的基础上,我会实现这样的事情:
public static List<IExample> GetExamples()
{
return GetInstances<IExample>().ToList();
}
private static IEnumerable<T> GetInstances<T>()
{
return Assembly.GetExecutingAssembly().GetTypes()
.Where(type => type.IsClass &&
!type.IsAbstract &&
type.GetConstructor(Type.EmptyTypes) != null &&
typeof (T).IsAssignableFrom(type))
.Select(type => (T) Activator.CreateInstance(type));
}
此解决方案会跳过无法实例化的类型,例如抽象类,派生接口和没有默认(无参数)公共构造函数的类。
答案 2 :(得分:0)
你必须使用反射。
Assembly.GetExecutingAssembly
应该是你的起点。
编辑:应该提供帮助的代码
Type[] types = Assembly.GetExecutingAssembly().GetTypes();
foreach(Type tp in types)
{
if (typeof(IExample).IsAssignableFrom(tp))
{
if (tp.IsInterface == false)
{
IExample t = Activator.CreateInstance(tp) as IExample;
Console.WriteLine(t.Foo());
}
}
}
答案 3 :(得分:0)
以下是我会做的事情:
public static List<IExample> GetExamples()
{
var assembly = Assembly.GetExecutingAssembly();
var types = assembly.GetTypes().Where(t => t.GetInterfaces().Any(i => i == typeof(IExample))).ToList();
List<IExample> returnMe = new List<IExample>();
foreach (var type in types)
returnMe.Add((IExample) Activator.CreateInstance(type));
return returnMe;
}