экземпляр списка моего имени класса, определенного в строке - PullRequest
0 голосов
/ 27 марта 2019

Я пытаюсь создать экземпляр списка с классом, определенным ранее в строковой переменной.Я даже не знаю, возможно ли это, но я думаю, что так.список с классом, который нужно использовать.

1 Ответ

1 голос
/ 27 марта 2019

Аргументы обобщенного типа для типа в C # не могут быть выражены свободно - они должны быть достаточно явными, поэтому, когда вы хотите смешать обобщенные значения и отражение, они всегда становятся немного беспорядочными.

Первая работа здесьэто получить Type, а не string.Если бы вы могли использовать typeof повсюду, это было бы намного проще, то есть

Type classToInstanciate;
if (condition) classToInstanciate = typeof(Class1);
else classToInstanciate = typeof(Class2);

В противном случае вам придется использовать Type.GetType(fullyQualifiedName) или someAssembly.GetType(fullName) и т. Д., Что становится беспорядочным.

Далее необходимо переключиться с отражения (Type) на генерики (<T>).Есть несколько способов сделать это, но самый простой из них: MakeGenericMethod.Например:

class SomeType {
    // can make this non-public, but then you need to specify BindingFlags
    // in the GetMethod call
    public static List<T> DoTheThing<T>(whateverArgs) {
        List<T> dtos = Parse<T>(source).ToList(); // whatever...
        ///
        return dtos;
    }
    ...
    private static IList CallTheThing(Type type, whateverArgs)
    {
        return (IList) typeof(SomeType).GetMethod(nameof(DoTheThing))
              .MakeGenericMethod(type).Invoke(null, whateverArgs);
        // "null" above is the target instance; in this case static, hence null
    }
    // ...
}

Тогда вы можете использовать:

IList list = CallTheThing(classToInstanciate, otherArgs);

list на сайте вызова (и должен быть) известен только как неуниверсальный IList API.Если вам нужно использовать общие аспекты (List<T> и т. Д.) - вы можете сделать это внутри DoTheThing<T>.* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

* * * * * * * * * * * * * * * * * * * * * * * * * * * * по-прежнему List<T> (правильного T), даже если он известен только как IList.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...