2014-06-10 28 views
2

我有一個通用的接口,我想有一個實施的數據類型的列表。 使用下面的代碼我沒有得到任何返回的類型。 (在類型T)獲取實施類型的通用接口

var type = typeof (IDataTypeConverter<>); 
var types = AppDomain.CurrentDomain.GetAssemblies() 
        .SelectMany(x => x.GetTypes()) 
        .Where(x => type.IsAssignableFrom(x) && !x.IsInterface); 

foreach (var t in types) 
{ 
    var instance = (IDataTypeConverter)Activator.CreateInstance(t); 
    PropertiesConverter.Add(t, instance); 
} 

這是接口的實現的例子:

public class DecimalConverter : IDataTypeConverter, IDataTypeConverter<decimal> 
    { 
    ... 
    } 

接口它的自我:

我在做什麼錯在這裏,你爲什麼不我在列表中獲得小數作爲類型嗎?

回答

2

你快到了。您正在檢查您的班級是否可以分配到開放式通用類型IDataTypeConverter<>,但他們不是。他們只分配給一個關閉泛型類型像IDataTypeConverter<decimal>(或其他數據類型TDataType

var type = typeof (IDataTypeConverter<>); 
var types = AppDomain.CurrentDomain.GetAssemblies() 
    .SelectMany(x => x.GetTypes()) 
    .Where(x => !x.IsInterface) //ignore interface definitions 
    .Where(x => x.GetInterfaces() //for each interface implemented 
     .Where(i => i.IsGenericType) //if they're a generic interface 
     .Any(i => i.GetGenericTypeDefinition() == type)); //check its open-generic 

我覺得可能是檢查一個簡單的方法,但是這將做的工作。它抓取一個類型的所有接口,並且爲每個接口定義一個通用接口,它檢查它是否是基礎開放泛型定義是IDataTypeConverter<>

編輯:另一種方式來證明我的意思,你現有的代碼將工作如果type您分配typeof(IDataTypeConverter<decimal>)代替。這是有效的,因爲你的類型可以分配到IDataTypeConverter<decimal>,但它們不能分配給IDataTypeConverter<>,因爲這樣的操作在C#中沒有意義。

+0

任何想法,我怎麼能拿接口的類型? IDataTypeConverter =十進制代替DecimalConverter – Freddy

+1

@Freddy:是的,一旦你有接口類型,你可以使用['GetGenericArguments()'](http://msdn.microsoft.com/en-us/library/system.type .getgenericarguments.aspx)來獲得'decimal'泛型參數。 –

2

您的類型變量包含泛型類型定義,IDataTypeConverter不是它的後代。所以IDataTypeConverter不能從IDataTypeConverter <>中分配。

Console.WriteLine(typeof(IDataTypeConverter<>).IsGenericTypeDefinition); 
Console.WriteLine(typeof(IDataTypeConverter<decimal>).IsGenericTypeDefinition); 

要檢查一些通用的類型,你可以使用謂詞相同的通用類型定義的:

x => .GetInterfaces() 
    .Any(item => item.IsGenericType && item.GetGenericTypeDefinition() == type) 
相關問題