2017-03-17 53 views
4

我有一个公共抽象类Client与两个继承类CustomerTimeWaster组合框项目显示解决方案中的类名称

我在C# Windows Forms上创建了一个下拉菜单,我想将这两个类名称显示为选项:Customer & TimeWaster。

所有我能想到的是创建一个简单的List包含这两个条款,然后在列表绑定到组合框DataSource

List<string> clientType = new List<string>() 
{ 
    "Customer", 
    "TimeWaster" 
}; 

public frmClientScreen() 
{ 
    cmboxClientType.DataSource = clientType; 
} 

但这不是维护,因为在将来,我可能添加许多其他我希望在下拉菜单中显示的名称的类。

如何将我的Visual Studio Solution中的类名称链接到组合框显示的项目?

+1

你正在谈论“类型发现”,而且要走的路是反思。看看这个问题:http://stackoverflow.com/questions/2362580/discovering-derived-types-using-reflection – Ishmaeel

+0

@Ishmaeel谢谢!类型的发现和反思对我来说是新的,所以我必须学习一个全新的概念。欢呼 – Joshua

回答

3

为了得到一组已知的类型的类型名称:

List<string> clientType = new List<string>() 
{ 
    nameof(Customer), 
    nameof(TimeWaster) 
}; 

public frmClientScreen() 
{ 
    cmboxClientType.DataSource = clientType; 
} 

至于动态获取从一个特定的类型派生的所有类型,这question显示了如何做到这一点的例子。

从这个问题接受的答案:

var listOfBs = (from domainAssembly in AppDomain.CurrentDomain.GetAssemblies() 
       from assemblyType in domainAssembly.GetTypes() 
       where typeof(B).IsAssignableFrom(assemblyType) 
       select assemblyType).ToArray(); 

B应与你的基类来代替。

然后,渐渐派生类型的列表之后,你可以做到以下几点:

var clientTypes = listOfBs.Select(x => x.Name).ToList(); 
+0

非常感谢。为了查看输出,我把这段代码放在'Main'中,但是它不返回任何东西,数组长度回到零。我的类可以在我的'Main'中看到,所以我想知道这个代码是否可以放在任何地方? – Joshua

+1

主要的是,许多程序集可能尚未加载,因为.Net使用“即时加载”。也就是说,程序集在使用之前不会被加载。主要的是,大多数程序集可能还没有加载,所以你得到一个空数组并不奇怪。 –

+0

明白了,谢谢。 – Joshua

2

我不得不这样做了许多不同的时间,到了那里我只是想一个全局函数点我可以使用。所以,我清理了一些常见的来源代码,并结束了:

public static class ReflectionHelper 
{ 
    public static List<T> GetAllNonabstractClassesOf<T>() 
    { 
     Object[] args = new Object[0]; 
     return GetAllNonabstractClassesOf<T>(args); 
    } 

    public static List<T> GetAllNonabstractClassesOf<T>(Object[] args) 
    { 
     List<T> retVal = new List<T>(); 
     IEnumerable<object> instances = from t in Assembly.GetExecutingAssembly().GetTypes() 
             where t.IsSubclassOf(typeof(T)) && !t.IsAbstract 
             select Activator.CreateInstance(t, args) as object; 
     foreach (T instance in instances) 
     { 
      retVal.Add(instance); 
     } 
     return retVal; 
    } 
} 

...然后,你可以简单地调用这样的代码:

List<myClass> = ReflectionHelper.GetAllNonabstractClassesOf<myClass>(); 

(或类中是否需要构造函数的参数,你可以使用第二个函数。)

无论如何,它的美妙之处在于,无论你想通过多少种不同的类来反映,你只需要通过你的代码一次就可以使用这个函数。

+0

这是天才!非常感谢你。 – Joshua

+1

请注意,这只会加载当前程序集中的类。如果您在不同的程序集中定义基类的子类,那么将不会使用此方法检索它。 –

相关问题