首页 > 解决方案 > 如何将动态模型作为“T”传递给 C# 泛型函数

问题描述

我有一个通用函数,如下所示

private List<T> GetAll<T>()
{
    var listOfTModels = // gets the list of T from the database.

    return listOfTModels;
}

我需要根据将在运行时确定的字符串将模型( T )动态传递给该函数。

public void SomeFunction(string modelName)
{
     // Call the above Get method with modelName parameter as the 'T'

     var listOfModels = GetAll<something>(); //not sure what type this something should be "Type" or "string"

     // Further Logic on listOfModels
}

怎么可能做到这一点?

标签: c#genericsdynamic

解决方案


您将需要使用反射来获得这样的方法:

typeof(ClassWithGetAll).GetMethod("GetAll",
                       BindingFlags.Instance | BindingFlags.NonPublic);

这将返回一个方法信息,然后您将使用它来通过MakeGenericMethod.

从字符串名称 AFAIK 获取类型的唯一方法是使用Type.GetType但您需要为此使用AssemblyQualifiedName,因此传入类似stringorint或类似名称的短/简化名称很可能会返回null

如果您弄清楚如何获取限定名称或如何搜索类型,最后一件事就是调用调用MethodInfo返回的MakeGenericMethod内容,下面是代码外观示例:

public void SomeFunction(string modelName)
{
    // No idea what the class/struct in which the method "GetAll" 
   // is called, hence use this name
    var instance = new ClassWithGetAll();

    //Retrieves the info of "GetAll<T>"
    MethodInfo method = typeof(ClassWithGetAll).GetMethod("GetAll", 
                        BindingFlags.Instance | BindingFlags.NonPublic);

    //Commented out as you will need to figure out how to get the 
    // assembly qualified name of the input model name, unless 
    // it is qualified.
    //modelName = GetAssemblyQualifiedName(modelName);

    Type modelType = Type.GetType(modelName);

    //Creates a generic method: "GetAll<T>" => "GetAll<modelType>"
    method = method.MakeGenericMethod(modelType);

    //Invokes the newly created generic method in the specified 
    // instance with null parameters, which returns List<modelType>
    object list = method.Invoke(instance, null);
}

推荐阅读