Как передать динамическую модель как 'T' в универсальную функцию C # - PullRequest
1 голос
/ 25 октября 2019

У меня есть общая функция, как показано ниже

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
}

Может кто-нибудь, пожалуйста, помогите мне с этим?

Ответы [ 2 ]

1 голос
/ 25 октября 2019

Вам потребуется использовать отражение, чтобы получить метод следующим образом:

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

Это вернет информацию о методе, которую вы затем будете использовать для создания универсального метода через MakeGenericMethod.

Единственный способ получить тип из строкового имени AFAIK - использовать Type.GetType , но для этого вам понадобится AssemblyQualifiedName , поэтому передается короткое / упрощенное имя типа string или int или что-то подобное, скорее всего, вернет null.

Если вы выясните, как получить квалифицированное имя или как искать тип, последнее, что нужно сделать, этовызовите MethodInfo, возвращенный из вызова MakeGenericMethod, вот пример того, как может выглядеть код:

public void SomeFunction(string modelName)
{
    //Sins i have no idea what the class/struct in which the method "GetAll" is called i will 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 the List<modelType>
    object list = method.Invoke(instance, null);
}
0 голосов
/ 25 октября 2019

Я думаю, что наследование будет правильным способом решения вашей проблемы.

public class TBase
{
    public int Prop { get; set; }
}
public class TChildOne : TBase
{

}
public class TChildTwo : TBase
{

}

public class GClass
{
    private List<T> GetAll<T>() where T : TBase
    {
        var listOfTModels = // gets the list of T from the database.
        return listOfTModels;
      }


    public void Main(string strType)
    {
        switch (strType)
        {
            case "TChildOne":
                {
                    var child = GetAll<TChildOne>();
                    break;
                }
            case "TChildTwo":
                {
                    var child = GetAll<TChildTwo>();
                    break;
                }
            default:
                throw new Exception("type not found");
        }

    }
}
...