[英]How to cast an object in generic collection?
我需要將一個對象轉換為通用集合,看:
var currentEntityProperties = currentEntity.GetType().GetProperties();
foreach (var currentEntityProperty in currentEntityProperties)
{
if (currentEntityProperty.PropertyType.GetInterfaces().Any(
x => x.IsGenericType &&
x.GetGenericTypeDefinition() == typeof(ICollection<>)))
{
var collectionType = currentEntityProperty.PropertyType.GetInterfaces().Where(
x => x.IsGenericType &&
x.GetGenericTypeDefinition() == typeof(ICollection<>)).First();
var argumentType = collectionType.GetGenericArguments()[0];
// now i need to convert the currentEntityProperty into a collection, something like that (this is wrong, so, what is thr right way?):
var currentCollection = (ICollection<argumentType.GetType()>)currentEntityProperty.GetValue(currentEntity, null);
}
}
我怎樣才能做到這一點?
觀察:我需要使用此集合來調用另一個集合的except方法(該集合我以與currentCollection相同的方式獲取,並使用anotherEntityProperty.GetValue(anotherEntity, null)
)
var itens = currentCollection.Except(anotherCollection);
動態類型使您可以使編譯器和DLR在這里完成所有工作:
dynamic currentCollection = ...;
dynamic anotherCollection = ...;
dynamic items = Enumerable.Except(currentCollection, anotherCollection);
在執行時,這將為您完成所有反射工作,並選擇最合適的type參數。
對於Except擴展方法,您只需要ICollection<T>
實現的IEnumerable<T>
。 因此,您可以將屬性轉換為IEnumerable<object>
(至少在T是引用類型的情況下)。
編輯:
如果確實需要,可以嘗試通過反射對對象變量調用Except:
// x and y are your object variables of the collections,
// argumentType is the generic type you determined
var methods = from m in typeof(Enumerable).GetMethods(BindingFlags.Static | BindingFlags.Public)
where m.ContainsGenericParameters
&& m.Name == "Except"
&& m.GetParameters().Count() == 2
&& m.GetParameters()[0].ParameterType.GetGenericTypeDefinition() == typeof(IEnumerable<>)
&& m.ReturnType.GetGenericTypeDefinition() == typeof(IEnumerable<>)
select m;
var method = methods.First();
IEnumerable things = method.MakeGenericMethod(new Type[] { argumentType }).Invoke(null, new [] { x, y }) as IEnumerable;
您不能使用ICollection<some_type_determined_at_run_time>
-編譯器將無法為其生成任何有意義的代碼。
如果類型與
-錯誤...此類轉換適用於IEnumerable(因為它的類型為“ out T”),但不適用於ICollection。 ICollection<Base_Class>
類型轉換相關
ICollection<Base_Class>
則應在4.0中工作
這不是直接回答您的問題,而是在評論中通過我們的討論回答問題:
如何使用反射調用Except方法?
Except方法不是ICollection<T>
的成員,這就是您的GetMethod調用返回null的原因。 相反,它是在靜態類型System.Linq.Enumerable
上定義的擴展方法。 要使用反射進行調用,您必須將其視為靜態方法。 像這樣:
// there are two overloads of Except and I'm too lazy to construct the type parameters to get the correct overload
var methods = typeof(Enumerable).GetMethods(BindingFlags.Static | BindingFlags.Public);
var exceptMethod = methods.Where(m => m.Name.Equals("Except") && m.GetParameters().Lengh == 2).Single();
object[] arguments = new [] { currentCollection, anotherCollection };
object items = exceptMethod.Invoke(null, arguments);
這是喬恩·斯基特(Jon Skeet)的“簡單方法”(C#4.0及更高版本):
dynamic items = Enumerable.Except((dynamic)currentCollection, (dynamic)anotherCollection);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.