使用反射从基本类型确定复杂类型

时间:2010-05-12 04:26:09

标签: c# reflection types metadata

我正在编写一个工具,我需要反思方法,如果方法的参数是复杂类型,那么我需要某些类型的操作,例如实例化它们等。

现在我在IsPrimitive变量中看到了Type属性。但是,它将stringdecimal显示为复杂类型,从技术上讲,这不是错误的。然而,我真正想要的是能够将开发人员创建的类类型与系统定义的数据类型区分开来。

我有什么方法可以做到这一点吗?

4 个答案:

答案 0 :(得分:8)

decimal 当然是“复杂类型”; C#可能有一个关键字,但它不是CLI原语。字符串你可以争论任何一种方式 - 它实际上是一种自身的类型(不确定的大小等 - 唯一可以远程比较的是数组)。

然而;根本没有办法确定你想要的东西。您可以做的 best 是检查已知的系统组件(或者可能是签名密钥)。毕竟, I 可以编写一个名为System.something.dllMicrosoft.something.dll的程序集,其中的类型位于System.Foo.Bar命名空间中(这也取决于当然,你想成为多么偏执。

可能更容易让开发者明确地标记他们想要以特定方式处理的类型 - 通过属性或接口。

答案 1 :(得分:4)

在我进行搜索时遇到了这个帖子。我一直在为此寻找解决方案,并发现您还可以检查命名空间以查看属性是否已在您自己的命名空间中定义。

if (property.PropertyType.Namespace.StartsWith("MyApp.MyNamespace"))
{ 
      // logic for properties in MyNamespace
}

希望这有助于某人。

答案 2 :(得分:2)

我不确定是否有更优雅的方法,但我想如果你根据命名空间System和/或系统程序集检查类型的Namespace或AssemblyQualifiedName,它将运行良好。

答案 3 :(得分:0)

不太确定使用内置类型与用户创建的类型有何不同。您更大的问题是创建没有无参数构造函数的类型的实例。

无论你做什么,你都必须将它们转换为对象数组,以便将它们传递给MethodInfo.Invoke,所以在某些时候你需要做Activator.CreateInstance

如果你提供一个UI,用户可以在字段中输入内容,然后按一个按钮来调用方法,你最好的策略是使用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
}