我有一个扩展方法:
public static List<object> ToModelViewObjectList<ModelViewType>(this IEnumerable<object> source)
{
List<ModelViewType> destinationList = new List<ModelViewType>();
PropertyInfo[] ModelViewProperties = typeof(ModelViewType).GetProperties();
foreach (var sourceElement in source)
{
object destElement = Activator.CreateInstance<ModelViewType>();
foreach (PropertyInfo sourceProperty in sourceElement.GetType().GetProperties())
{
if (ModelViewProperties.Select(m => m.Name).Contains(sourceProperty.Name))
{
destElement.GetType().GetProperty(sourceProperty.Name).SetValue(destElement, sourceProperty.GetValue(sourceElement));
}
}
destinationList.Add((ModelViewType)destElement);
}
return destinationList.Cast<object>().ToList();
}
我有一个带有对象列表的方法,我希望在这个方法中使用调用扩展方法:
public void GridModel(IEnumerable<object> GridDataSource)
{
List<object> list = GridDataSource.ToModelViewObjectList<GridDataSource[0].GetType()>();
}
我应该写什么而不是GridDataSource [0] .GetType()?
我有一个带对象参数的方法。我想创建一个对象类型的通用列表。
public void CreateListByNonGenericType(object myObject)
{
Type objType = myObject.GetType();
var lst = System.Collections.Generic.List < objType.MakeGenericType() > ();
}
我应该写什么而不是objType.MakeGenericType()
?
答案 0 :(得分:7)
我应该写什么而不是
GridDataSource[0].GetType()
?
因为您在编译时不知道类型,所以必须在运行时执行所有操作。所以你需要从方法定义中创建一个泛型方法并调用它。如下所示:
GridModel(IEnumerable<object> GridDataSource)
{
Type dataSourceElementType = GridDataSource[0].GetType();
//MyExtension is a type where ToModelViewObjectList defined
MethodInfo methodDefinition = typeof(MyExtension).GetMethod("ToModelViewObjectList");
//https://msdn.microsoft.com/en-us/library/system.reflection.methodinfo.makegenericmethod
MethodInfo method = methodDefinition.MakeGenericMethod(dataSourceElementType)
//https://msdn.microsoft.com/en-us/library/a89hcwhh
List<object> list = (List<object>)method.Invoke(GridDataSource, null);
}
但你真正想做的是接受ToModelViewObjectList的类型作为参数而不是泛型类型参数,如下所示,因为在返回对象列表时不使用函数外部的ModelViewType。此外,它将使您的代码清晰。
public static List<object> ToModelViewObjectList(this IEnumerable<object> source, Type modelViewType)
{
List<object> destinationList = new List<object>();
PropertyInfo[] ModelViewProperties = modelViewType.GetProperties();
foreach (var sourceElement in source)
{
object destElement = Activator.CreateInstance(modelViewType);
foreach (PropertyInfo sourceProperty in sourceElement.GetType().GetProperties())
{
if (ModelViewProperties.Select(m => m.Name).Contains(sourceProperty.Name))
{
destElement.GetType().GetProperty(sourceProperty.Name).SetValue(destElement, sourceProperty.GetValue(sourceElement));
}
}
destinationList.Add(destElement);
}
return destinationList;
}
所以你可以像你想要的那样调用这个扩展方法:
List<object> list = GridDataSource.ToModelViewObjectList(GridDataSource[0].GetType());
此外,使用其他东西获取GridDataSource的元素类型比获取第一个元素的类型更好。
答案 1 :(得分:5)
public void CreateListByNonGenericType(object myObject)
{
Type objType = myObject.GetType();
Type listType = typeof(List<>).MakeGenericType(objType);
//We can not use here generic version of the interface, as we
// do not know the type at compile time, so we use the non generic
// interface IList which will enable us to Add and Remove elements from
// the collection
IList lst = (IList)Activator.CreateInstance(listType);
}
答案 2 :(得分:1)
如果你知道你的参数是&#34;对象&#34;只键入你可以创建&#34;对象&#34;的列表类型。在使用列表时将其转换为特定类型。
public void CreateListByNonGenericType(object myObject)
{
object objType = myObject.GetType();
var lst = new List<object>();
lst.Add(myObject);
}
但是如果在调用方法之前知道对象的类型,可以使用像这样的Generic方法。
public void CreateListByNonGenericType<T>(T myObject, string s)
{
var lst = new List<T>();
lst.Add(myObject);
}