C# 反射:如何获取 Nullable的类型?

发布于 2024-12-21 18:42:55 字数 387 浏览 5 评论 0原文

我想做的是这样的:

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

object.GetType() 下的什么路径将具有我可以使用 case 语句进行比较的数据类型的字符串名称?我需要知道类型,这样我就可以使用 Convert.ToInt32( string ) 之一来使用反射设置 myObject 的值。

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? 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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

十雾 2024-12-28 18:42:55

我一直在使用以下类型的代码来检查类型是否可为空并获取实际类型:

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

如果类型为例如可为空,则此代码返回 int 部分(基础类型)。如果您只需要将对象转换为特定类型,您可以使用 System.Convert .ChangeType 方法。

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 e.g. Nullable this code returns the int part (underlying type). If you just need to convert object into specific type you could use System.Convert.ChangeType method.

一绘本一梦想 2024-12-28 18:42:55

这个问题很令人困惑。 “myObject”是可能为 nullable int 的对象吗?或者属性“id”可能是 nullable int 类型?

如果是前者,你的问题就无法得到回答,因为它预设了一个谎言。不存在装箱可为 null int 之类的东西。我注意到,所有建议 if (myobject.GetType() == typeof(int?)) 的答案都是不正确的;该条件永远不会为真。

将 nullable int 转换为对象时,它要么成为 null 引用(如果该 nullable int 没有值),要么成为装箱 int。无法确定对象是否包含可为 null int,因为对象从不包含可为 null int。

如果是后者,请将属性类型typeof(int?)进行比较。您不能使用开关;只有常量可以用于 switch 情况,并且类型不是常量。

总而言之,这是一种糟糕的代码味道。你为什么首先使用反射?

The question is very confusing. Is "myObject" the object that might be a nullable int? Or is the property "id" possibly of type 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. I note that all of the answers which propose if (myobject.GetType() == typeof(int?)) are therefore incorrect; 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. There is no way to determine if an object contains a nullable int because an object never contains a nullable int.

If the latter, compare the property type to 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?

那片花海 2024-12-28 18:42:55

更新:看起来 C# 7 将支持打开 Type,就像这个问题的提问者试图做的那样。但它有点不同,所以要小心语法地雷。

您不需要字符串名称来比较它:

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

Update: Looks like C# 7 will support switching on Types as the asker of this question was trying to do. 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
多像笑话 2024-12-28 18:42:55

在 .net 中,值类型的实例只是位的集合,没有关联的类型信息。然而,对于除 Nullable之外的每个值类型,系统还会自动生成派生自 System.ValueType 的相应类类型。存在从值类型到自动生成的类类型的扩大转换,以及从自动生成的类类型到值类型的缩小转换。对于Nullable,没有相应的自动生成的类类型与值类型之间的转换;相反,Nullable 和与 T 关联的类类型之间存在双向扩展转换。

据我所知,实现这种奇怪的行为是为了允许 null 和空的 Nullable 之间的比较返回 true。

In .net, instances of value types are just collections of bits, with no associated type information. For every value type other than Nullable<T>, however, the system also auto-generates a corresponding class type which derives from 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; instead, widening conversions exist in both directions between Nullable<T> and the class type associated with 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.

倾听心声的旋律 2024-12-28 18:42:55

正如 @Cody Gray 所说, if 语句可能是最好的方法

var t = myObject.GetType();

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

As @Cody Gray said if statements would probably be the best way

var t = myObject.GetType();

if (t == typeof(Nullable<int>))
{ }
else if (t == typeof(string))
{}
else if (t==typeof(Nullable<bool>))
{}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文