Я пишу инструмент, где я должен размышлять над методами и если параметры методов являются составным типом, то мне нужно к определенному типу действий, таких как инстанцирование их и т.д.
Теперь я видел IsPrimitive
свойство в Type
переменная. Однако это показывает string
и decimal
как составные типы, который технически не является неправильным. Однако то, что я действительно хочу, должно смочь различать, разработчик создал типы классов из системных определенных типов данных.
Есть ли какой-либо способ, которым я могу сделать это?
decimal
certainly - это "сложный тип"; C# может иметь ключевое слово для него, но это не примитив CLI. Со строкой можно поспорить в любом случае - это фактически тип сам по себе (неопределенный размер и т.д. - единственные вещи, отдаленно сравнимые с ней, это массивы).
Однако; просто нет способа определить, что вы хотите здесь получить. Лучшее, что вы можете сделать, это проверить известные системные сборки (или, возможно, ключи подписи). В конце концов, я могу написать сборку под названием System.something.dll
или Microsoft.something.dll
, с типами в пространстве имен System.Foo.Bar
(это также зависит от того, насколько параноидальным вы хотите быть, конечно).
Возможно, будет проще заставить разработчиков явно пометить свои собственные типы, которые вы хотите рассматривать особым образом - либо через атрибут, либо через интерфейс.
Не совсем понимаю, чем использование встроенных типов отличается от типов, созданных пользователем. Ваша большая проблема заключается в создании экземпляров типов, которые не имеют конструкторов без параметров.
Что бы вы ни делали, вам придется преобразовывать их в массивы объектов, чтобы передать их в 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
}
Я не уверен, есть ли более элегантный метод, но я полагаю, что если вы проверите Namespace или AssemblyQualifiedName типа на соответствие namespace System и/или системным сборкам, то все будет работать нормально.