#c# #generics #reflection
Вопрос:
Я использую .net Core 5.0.302 и испытываю проблемы с использованием отражения для вызова универсального метода
Функция заключается в
public static T Parse<T>(List<Token> tokenList, int startPos) where T : new(){
if(tokenList[startPos].tokenData.ToString() == "["){
// ParseArray(tokenList);
throw new NotImplementedException();
}
else if(tokenList[startPos].tokenData.ToString() == "{"){
return ParseObject<T>(tokenList, startPos);
}else{
T retVal = new T();
retVal = (T)tokenList[startPos].tokenData;
return retVal;
}
}
Код, который пытается вызвать этот метод, находится здесь —
MethodInfo method = typeof(JsonParser).GetMethod(nameof(JsonParser.Parse), BindingFlags.Static | BindingFlags.Public);
method = method.MakeGenericMethod(typeof(string));
object parsedType = method.Invoke(null, new object[]{tokenList, i 3});
props[z].SetValue(typeInst, parsedType);
И это сообщение об ошибке, которое я получаю
Система.Безопасность.Исключение проверки : Метод ParseLib.JsonParser.Разбор: введите систему аргументов.Строка» нарушает ограничение параметра типа «T». Трассировка стека: в System.RuntimeType.ВалидатеГенерикАргументы(определение MemberInfo, тип RuntimeType[] Общие аргументы, исключение e) в системе.Отражение.RuntimeMethodInfo.MakeGenericMethod(Тип[] Установка метода) в ParseLib.JsonParser.ParseObject[T](Список
1 tokenList, Int32 startPos) in /home/user/Projects/MyProjects/JsonParseSharp/ParseLib/JsonParser.cs:line 54 at ParseLib.JsonParser.Parse[T](List
1, начальные точки ввода 32) в /home/user/Проекты/MyProjects/JsonParseSharp/ParseLib/JsonParser.cs:строка 15 в парсетестах.JsonParserTest.TestParseBasicObject() в /главная/пользователь/Проекты/MyProjects/JsonParseSharp/ParseTests/JsonParserTest.cs:строка 16 —— Внутренняя трассировка стека —— в System.RuntimeMethodHandle.GetStubIfNeeded(метод RuntimeMethodHandleInternal, тип запуска, объявляющий тип, установка метода RuntimeType []) в системе.Отражение.RuntimeMethodInfo.MakeGenericMethod(Тип[] Установка метода)
Не смог понять, почему Система.Строка нарушает параметр типа «T». Если я заменю typeof(строка) на typeof(int), все будет работать так, как ожидалось. У кого-нибудь есть какие-либо идеи, в чем может быть проблема здесь?
Заранее спасибо!
Комментарии:
1.
string
не имеет конструктора без параметров.: new(){
2. Ах, это сделало бы sense…is есть ли какой-либо способ добавить конструктор без параметров в строку, или если мне нужно, чтобы моя универсальная функция была <string>, мне просто придется обращаться с этим случаем по-другому?
3. Да, вам понадобится какая-то другая техника для струн, увы.
4. Кстати, если бы вы повторили это, вызвав функцию напрямую (т. Е. Не через отражение) в качестве теста, вы, вероятно, получили бы то же или аналогичное сообщение об ошибке. Но без усложнения размышлений вы, вероятно, могли бы это понять. Я пишу много маленьких тестовых программ помимо кода, который я пишу
Ответ №1:
where T : new()
Ваш метод синтаксического анализа имеет ограничение типа, указывающее, что тип T должен иметь открытый конструктор без параметров.
в c# для построения строки конструктору строк требуется по крайней мере один параметр.
var str = new string("abc")
Но int может быть создан с помощью конструктора без параметров:
var num = new int()