【问题标题】:How to differentiate between value-type, nullable value-type, enum, nullable-enum, reference-types through reflection?如何通过反射区分值类型、可空值类型、枚举、可空枚举、引用类型?
【发布时间】:2011-12-23 09:59:41
【问题描述】:

如何通过反射区分value-type、nullable value-type、enum、nullable-enum、reference-types?

enum MyEnum
    {
        One,
        Two,
        Three
    }

    class MyClass
    {
        public int IntegerProp { get; set; }
        public int? NullableIntegerProp { get; set; }
        public MyEnum EnumProp { get; set; }
        public MyEnum? NullableEnumProp { get; set; }
        public MyClass ReferenceProp { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {   
            Type classType = typeof(MyClass);

            PropertyInfo propInfoOne = classType.GetProperty("IntegerProp");
            PropertyInfo propInfoTwo = classType.GetProperty("NullableIntegerProp");
            PropertyInfo propInfoThree = classType.GetProperty("EnumProp");
            PropertyInfo propInfoFour = classType.GetProperty("NullableEnumProp");
            PropertyInfo propInfoFive = classType.GetProperty("ReferenceProp");

            propInfoOne.???
            ...............
            ...............
        }
    }

可以在propInfo...s 中的什么位置检索这些信息?

【问题讨论】:

  • 如何定义“基本类型”?
  • int、float、double........正如你在 MyClass-props 中看到的那样。值类型。
  • 那么自定义结构呢?例如,我不明白为什么要将枚举与其他值类型区分开来。
  • 以上代码中没有值类型,值类型是一个结构体..这和原始类型不同。

标签: c# reflection propertyinfo


【解决方案1】:

这是检查枚举、可为空、原始和值类型的方法;

Console.WriteLine(propInfoOne.PropertyType.IsPrimitive); //true
Console.WriteLine(propInfoOne.PropertyType.IsValueType); //false, value types are structs

Console.WriteLine(propInfoThree.PropertyType.IsEnum); //true

var nullableType = typeof (Nullable<>).MakeGenericType(propInfoThree.PropertyType);
Console.WriteLine(nullableType.IsAssignableFrom(propInfoThree.PropertyType)); //true

请注意,值类型和原语是不同的东西。原语只是映射到类型的简写(例如 bool > System.Boolean)。值类型是按值传递的;它们是结构(ure)而不是类。

【讨论】:

  • @Programming Hero:你能告诉我Type.IsPrimitive 属性是什么意思吗?
  • @ProgrammingHero 这不太正确;原语通常是指那些具有直接 IL 支持的原语;例如,intshortbytelongfloat 等都具有 direct IL 支持; + 等操作不使用类型运算符,而是 IL 指令。例如,对比decimal,它不是原语。他们非常受到不同的对待。事实上,在堆栈中,它们中的大多数甚至都不存在:bytesbyteshortushort 等都在 IL 级别使用 int(在操作期间;而不是作为它们的声明)。
  • @Myles - 检查Nullable&lt;T&gt; 的更好方法是使用Nullable.GetUnderlyingType
  • 有人可以评论一下为什么这不是现在的答案吗?
  • 我看到你相信值类型存储在堆栈上的谎言。值类型存储在堆栈中,除非它们不存储在堆栈中,几乎总是这样。
【解决方案2】:
    public void Test(Type desiredType, object value)
    {
        if (desiredType.IsGenericType)
        {
            if (desiredType.GetGenericTypeDefinition() == typeof(Nullable<>))
            {
                if (value == null)
                {
                }
            }
        }
    }

【讨论】:

    【解决方案3】:

    PropertyType.Name 似乎为 Non Nullable 和 Nullable 类型提供了不同的输出。可能这对你有点帮助。

    实际上它给出了 Nullable`1 Int32 作为 Nullable 和 Non nullable 的输出。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-10-18
      • 1970-01-01
      • 1970-01-01
      • 2021-12-02
      • 1970-01-01
      • 2013-01-11
      • 2019-03-31
      相关资源
      最近更新 更多