我正在开发c#/。.NET 3.5应用程序(并希望继续使用该版本的。NET),不知道如何使用反射解决这个问题。我找到了解决办法,但不是"整洁"。代码如下,我需要发现所有的接口实现,以便在将来添加更多的接口实现时,我不需要改变现有的代码。
interface Ii { }
class A : Ii { }
class A1 : A { }
class A2 : A { }
class A3 : A { }
class B : Ii { }
class C : Ii{ }
// maybe in future class D : Ii { }
// maybe in future class E : Ii { }
class Helper
{
static List<Type> GetAllInterfaceImplemenations()
{// do reflection magic and return ["A1","A2","A3","B","C"] ...
// I will use this method to fill comboBox-es , create objects factory, etc...
// there should be no changes if/when in future I add class D etc.
}
}
试试这个:
public static List<string> GetAllInterfaceImplemenations()
{
var interfaceType = typeof(Ii);
var list = new List<string>();
foreach (var type in Assembly.GetExecutingAssembly().GetTypes())
{
if (type.IsClass && interfaceType.IsAssignableFrom(type))
{
list.Add(type.Name);
}
}
return list;
}
上述解决方案的问题是,它将从上面的例子返回类" A ",这是不希望的。只需要"叶子"。但是,上面的解决方案给出了如何解决它的想法。所以,这是我的生产解决方案(对不起,伙计们,ArrayList是我最喜欢的集合…)。
private static ArrayList GetAllInterfaceImplemenations()
{
ArrayList listOfLeafsNames = null;
try
{
Type interfaceType = typeof(ISpeechCodec);
ArrayList listOfAll = new ArrayList();
foreach (Type type in Assembly.GetExecutingAssembly().GetTypes())
{
if (type.IsClass && interfaceType.IsAssignableFrom(type))
{
listOfAll.Add(type);
}
}
listOfLeafsNames = new ArrayList();
foreach (Type typeCandidate in listOfAll)
{
bool isLeaf = true;
foreach (Type type2 in listOfAll)
{
if (!(typeCandidate.Equals(type2)))
{
if (typeCandidate.IsAssignableFrom(type2))
{
isLeaf = false;
}
}
}
if (isLeaf)
{
listOfLeafsNames.Add(typeCandidate.FullName);
}
}
}
catch (Exception ex)
{
Setup_TraceExceptions(ex.ToString());
}
return listOfLeafsNames;
}