如何从对象类型定义泛型类型

本文关键字:定义 泛型类型 类型 对象 | 更新日期: 2023-09-27 18:28:37

我有一个扩展方法:

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()

如何从对象类型定义泛型类型

我应该写什么而不是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的元素类型,而不是获取第一个元素的类型。

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);
}

如果您知道您的参数是"object"类型,则只能创建"object"型列表。在使用list时,将其强制转换为特定类型,如下所示。

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);
}