определите составной тип от типа примитива с помощью отражения

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

Теперь я видел IsPrimitive свойство в Type переменная. Однако это показывает string и decimal как составные типы, который технически не является неправильным. Однако то, что я действительно хочу, должно смочь различать, разработчик создал типы классов из системных определенных типов данных.

Есть ли какой-либо способ, которым я могу сделать это?

10
задан GibralterTop 27 June 2017 в 19:41
поделиться

3 ответа

decimal certainly - это "сложный тип"; C# может иметь ключевое слово для него, но это не примитив CLI. Со строкой можно поспорить в любом случае - это фактически тип сам по себе (неопределенный размер и т.д. - единственные вещи, отдаленно сравнимые с ней, это массивы).

Однако; просто нет способа определить, что вы хотите здесь получить. Лучшее, что вы можете сделать, это проверить известные системные сборки (или, возможно, ключи подписи). В конце концов, я могу написать сборку под названием System.something.dll или Microsoft.something.dll, с типами в пространстве имен System.Foo.Bar (это также зависит от того, насколько параноидальным вы хотите быть, конечно).

Возможно, будет проще заставить разработчиков явно пометить свои собственные типы, которые вы хотите рассматривать особым образом - либо через атрибут, либо через интерфейс.

8
ответ дан 3 December 2019 в 22:35
поделиться

Не совсем понимаю, чем использование встроенных типов отличается от типов, созданных пользователем. Ваша большая проблема заключается в создании экземпляров типов, которые не имеют конструкторов без параметров.

Что бы вы ни делали, вам придется преобразовывать их в массивы объектов, чтобы передать их в MethodInfo.Invoke, поэтому в какой-то момент вам придется сделать Activator.CreateInstance.

Если вы предоставляете пользовательский интерфейс, где пользователь может вводить данные в поля, а затем нажимать кнопку для вызова метода, то лучшей стратегией будет использование Reflection для поиска статических методов TryParse/Parse для типа и вызова этих методов для проверки/разбора вводимых данных.

Вот фрагмент, который будет неявно работать для большинства системных типов, которые могут быть преобразованы из строки:

var parseMethod = typeof(int).GetMethods().FirstOrDefault(
    m => m.IsStatic && 
        m.Name == "TryParse" && 
        m.GetParameters().Length == 2 && 
        m.GetParameters()[0].ParameterType == typeof(string) && 
        m.GetParameters()[1].IsOut);
if(parseMethod != null) {
    bool result = (bool)parseMethod.Invoke(null, new object[]{"45", null});
    //result == true
    result = (bool)parseMethod.Invoke(null, new object[] { "blah", null });
    //result = false
}
0
ответ дан 3 December 2019 в 22:35
поделиться

Я не уверен, есть ли более элегантный метод, но я полагаю, что если вы проверите Namespace или AssemblyQualifiedName типа на соответствие namespace System и/или системным сборкам, то все будет работать нормально.

2
ответ дан 3 December 2019 в 22:35
поделиться
Другие вопросы по тегам:

Похожие вопросы: