2015-05-26 18 views
0

我在內存中有IEnumerable<object>從對象列表和調用通用方法創建運行時已知類型列表

讓我們這樣說:

IEnumerable<object>() addedEntities = // ... some Linq-To-Object query 

另外,我有一個方法與此簽名:

public static IEnumerable<TSource> FilterByUniqueProp<TSource> 
       (this IEnumerable<TSource> query, TSource model) 
{ 
     // Do something according to this type 
     var type = model.GetType(); 
} 

正如你看到的,這是一個擴展方法。所以,我不能動態調用它,我必須使用MethodInfo在運行時執行它。

在運行時,我必須動態調用此方法的一些Enumerable<T>運行時已知的類型。 但是,我所做的並不重要,它不起作用。 model.GetType()總是Object或拋出異常。

類型的對象 'System.Linq.Enumerable + WhereSelectArrayIterator 2[System.Data.Objects.ObjectStateEntry,System.Object]' cannot be converted to type System.Collections.Generic.IEnumerable 1 [PersonDetail]'。

這裏是我試過:

IEnumerable<object>() addedEntities = // ... some Linq-To-Object query 

Type listType = typeof(List<>); 
Type constructed = listType.MakeGenericType(model.GetType()); 
dynamic myList = Activator.CreateInstance(constructed); 
myList = addedEntities; 

MethodInfo mesthod = typeof(DynamicLinqExtensions).GetMethod("FilterByUniqueProp"); 
MethodInfo genericMethod= mesthod.MakeGenericMethod(model.GetType()); 
dynamic sameEntitiesInContext = genericMethod.Invoke(this, new object[] { myList, model }); 
+0

IEnumerable <>'中的類型都是單個類型或多個類型?那麼所有的'PersonDetail'或者他們可以是一個'PersonDetail' **加上**一個'DogDetail'? – xanatos

+0

@xanatos所有的單一類型。 –

+0

等等...你有'model'對象,所以你可以檢查它的類型,對吧? – xanatos

回答

1

很簡單:

public static class DynamicLinqExtensions 
{ 
    public static IEnumerable<TSource> FilterByUniqueProp<TSource> 
      (this IEnumerable<TSource> query, TSource model) 
    { 
     // Do something accourding to this type 
     var type = typeof(TSource); 
     return null; 
    } 

    public static IEnumerable<TSource> FilterByUniqueProp2<TSource> 
      (this IEnumerable<object> query, TSource model) 
    { 
     // We use Cast<>() to conver the IEnumerable<> 
     return query.Cast<TSource>().FilterByUniqueProp<TSource>(model); 
    } 
} 

您使用.Cast<>

這樣使用它:

// Your data 
IEnumerable<object> addedEntities = new object[] { new MyClass(), new MyClass() }; 
object model = new MyClass(); 

// The needed code 
Type type = model.GetType(); 

MethodInfo method = typeof(DynamicLinqExtensions) 
      .GetMethod("FilterByUniqueProp2") 
      .MakeGenericMethod(type); 

method.Invoke(null, new object[] { addedEntities, model }); 

注意,事實上,你可以直接改變FilterByUniquePropr到簽名:

public static IEnumerable<TSource> FilterByUniqueProp<TSource> 
     (this IEnumerable<object> query, TSource model) 
{ 
    var query2 = query.Cast<TSource>(); 

    var type = typeof(TSource); 

    return null; 
} 

和使用反射來調用directl這個方法!

+0

感謝您的回答。但是,它會拋出異常'對於ContainsGenericParameters爲true的類型或方法,無法對後期操作執行。' –

+0

@FarhadJabiyev您忘了將'MakeGenericMethod()'放在某處 – xanatos

+0

謝謝,它可行。說實話只有我忘了用'Cast '。再次感謝。 –

相關問題