Функция универсального типа C#, Сделать общий метод Не работает с системой.Строка

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