简体   繁体   English

C#反思:如何获取Nullable的类型 <int> ?

[英]C# Reflection: How to get the type of a Nullable<int>?

What I want to do is something like this: 我想做的是这样的:

switch( myObject.GetType().GetProperty( "id") )
{
    case ??: 
        // when Nullable<Int32>, do this
    case ??:
        // when string, do this
    case ??:
        // when Nullable<bool>, do this

What path under object.GetType() would have the string name of the datatype that I could compare using a case statement? object.GetType()下的什么路径将具有我可以使用case语句进行比较的数据类型的字符串名称? I need to know the type so I can have one of many Convert.ToInt32( string ) that will set the value of myObject using Reflection. 我需要知道类型,所以我可以使用许多Convert.ToInt32(字符串)中的一个,它将使用Reflection设置myObject的值。

I've been using the following type of code to check if the type is nullable and to get the actual type: 我一直在使用以下类型的代码来检查类型是否可以为空并获取实际类型:

if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
{
    return Nullable.GetUnderlyingType(type);
}

If the type is eg Nullable this code returns the int part (underlying type). 如果类型是例如Nullable,则此代码返回int部分(基础类型)。 If you just need to convert object into specific type you could use System.Convert.ChangeType method. 如果您只需要将对象转换为特定类型,则可以使用System.Convert.ChangeType方法。

The question is very confusing. 这个问题非常令人困惑。 Is "myObject" the object that might be a nullable int? “myObject”是否可能是一个可以为空的int? Or is the property "id" possibly of type nullable int? 或者属性“id”可能是类型为nullable int?

If the former, your question cannot be answered because it presupposes a falsehood. 如果是前者,你的问题无法回答,因为它预示着虚假。 There is no such thing as a boxed nullable int. 没有像盒装的可空int那样的东西。 I note that all of the answers which propose if (myobject.GetType() == typeof(int?)) are therefore incorrect; 我注意到所有提出if (myobject.GetType() == typeof(int?))的答案都是错误的; the condition will never be true. 这种情况永远不会成真。

When you convert a nullable int to object, either it becomes a null reference (if the nullable int had no value) or it becomes a boxed int. 将nullable int转换为object时,要么变为空引用(如果nullable int没有值),要么变为boxed int。 There is no way to determine if an object contains a nullable int because an object never contains a nullable int. 无法确定对象是否包含可空int,因为对象永远不会包含可为空的int。

If the latter, compare the property type to typeof(int?) . 如果是后者,请将属性类型typeof(int?) You cannot use a switch; 你不能使用开关; only constants may be used for switch cases and types are not constants. 只有常量可用于开关案例,类型不是常量。

All that said, this is a bad code smell. 总而言之,这是一个糟糕的代码味道。 Why are you using reflection in the first place? 为什么你首先使用反射?

Update: Looks like C# 7 will support switching on Type s as the asker of this question was trying to do. 更新:看起来C#7将支持切换Type s,因为这个问题的提问者试图做。 It's a little different though so watch out for syntax landmines. 这有点不同,但要注意语法地雷。

You don't need a string name to compare it: 您不需要字符串名称来比较它:

if (myObject.GetType().GetProperty("id").PropertyType == typeof(Nullable<Int32>))
    // when Nullable<Int32>, do this
else if (myObject.GetType().GetProperty("id").PropertyType == typeof(string))
    // when string, do this
else if (myObject.GetType().GetProperty("id").PropertyType == typeof(Nullable<bool>))
    // when Nullable<bool>, do this

In .net, instances of value types are just collections of bits, with no associated type information. 在.net中,值类型的实例只是位的集合,没有关联的类型信息。 For every value type other than Nullable<T> , however, the system also auto-generates a corresponding class type which derives from System.ValueType . 但是,对于Nullable<T>以外的每个值类型,系统还会自动生成从System.ValueType派生的相应类类型。 A widening conversion exists from the value type to the auto-generated class type, and a narrowing conversion from the auto-generated class type to the value type. 存在从值类型到自动生成的类类型的扩展转换,以及从自动生成的类类型到值类型的缩小转换。 In the case of Nullable<T> , there is no corresponding auto-generated class type with conversions to/from the value type; Nullable<T>的情况下,没有相应的自动生成的类类型,其中包含与值类型的转换; instead, widening conversions exist in both directions between Nullable<T> and the class type associated with T . 相反,在Nullable<T>和与T相关联的类类型之间的两个方向上存在加宽转换。

As far as I can tell, this weird behavior was implemented to allow comparisons between null and an empty Nullable<T> to return true. 据我所知,实现了这种奇怪的行为,以允许null和空Nullable<T>之间的比较返回true。

As @Cody Gray said if statements would probably be the best way 正如@Cody Gray所说,如果陈述可能是最好的方式

var t = myObject.GetType();

if (t == typeof(Nullable<int>))
{ }
else if (t == typeof(string))
{}
else if (t==typeof(Nullable<bool>))
{}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM