2011-08-31 84 views
3

当它为空时,是否可以检测到Nullable类型(转换为对象)?检测可空类型

由于Nullable<T>是一个真正的结构,我认为它应该是可能的。

double? d = null; 
var s = GetValue(d); //I want this to return "0" rather than "" 

public string GetValue(object o) 
{ 
    if(o is double? && !((double?)o).HasValue) //Not working with null 
     return "0"; 
    if(o == null) 
     return ""; 
    return o.ToString(); 
} 
+0

如果接受'object'类型的参数的例程被传递了'Nullable '类型的变量,那么例程将接收到一个空对象引用(如果该变量为null)或者对' System.Double'(如果变量不是null)。它不会包含一个'Nullable '的实例。 – supercat

回答

5

http://msdn.microsoft.com/en-us/library/ms228597(v=vs.80).aspx

对象如果对象是 非空仅装箱。如果HasValue为false,那么,而不是装箱,将对象 引用简单地分配给null。

如果对象非空 - 如果HasValue为真 - 然后拳击需要 的地方,但只有基础类型的可空对象是基于是盒装 。

所以你要么有double要么有null

public string GetValue(object o) 
{ 
    if(o == null) // will catch double? set to null 
     return ""; 

    if(o is double) // will catch double? with a value 
     return "0"; 

    return o.ToString(); 
} 
+0

所以答案是否定的,这是不可能的。感谢您的解释。 – Magnus

+0

@Magnus但请记住Skeet告诉你的。有一种方法,但不是通过拳击。最后,一切都取决于你想要做什么。 – xanatos

5

对于每个Nullable类型,您都有方法GetValueOrDefault,是不是够了?基于空类型

+0

因为我在函数中使用'object',所以我需要将它转换为Nullable 才能使用该函数。 (在我的例子中) – Magnus

+1

你不需要你使用这个方法的函数,你可以执行GetDateOrDefault()。ToString() –

+0

Yeh,但这是一个适用于所有类型的通用格式化函数。我希望能够检测到所有为空的Nullable数字类型,并返回“0”。 – Magnus

0

如果onull然后o is double?将是错误的。无论您的输入参数的值如何,您的输入参数值double? d

3

您的方法当前需要object,这意味着可以计数的值将被装箱......并且将不再是可以为空的值。 o的值将是或者是是不可为空的类型的装箱值或空引用。

如果可能的话,改变你的方法是通用的:

public string GetValue<T>(T value) 
{ 
    // Within here, value will still be a Nullable<X> for whatever type X 
    // is appropriate. You can check this with Nullable.GetUnderlyingType 
} 
+0

只是为了更清楚地说明这一点,这意味着在内存中的null和盒式空可引用类型之间没有区别。所以从方法中无法分辨出来。 – Iravanchi

+2

@Iravanchi:我会比这更强烈地说:根本不存在盒装可空类型* *。装箱可空类型值的结果是*或者*装箱的不可空类型或空引用。 –

+0

感谢您的回答。不幸的是,对象在到达GetValue函数之前被装箱,所以我不能使用你的通用示例。 – Magnus

-1

从我的理解,如果你想检测是否有对象为空,这可以很容易写。

试试这个...

public static bool IsNullable(dynamic value) 
{ 
    try 
    { 
     value = null; 
    } 
    catch(Exception) 
    { 
     return false; 
    } 
    return true; 
} 

简单!

+0

即使我们调用'IsNullable(5)','value = null'语句也会覆盖'object'类型的存储位置,而不是'int'类型。 – supercat

+0

你是对的。事后看来,我没有仔细检查过这个。理想情况下,最优雅的解决方案(至少在.net中)应检查对象是否是类或结构,并确定对象的“可空性”。我相信我的理解是正确的,结构不能为null,因为它们是堆栈中存在的值类型,而类是存在于堆中的引用类型,因此是引用而不是绝对值。我要走开并进一步调查。 – series0ne

+0

.net中有三种可转换为“对象”的东西:可为空的值类型,不可为空的值类型和对象。请注意,值类型不是对象,即使每个不可为空的值类型都具有可隐式转换的关联的“装箱”对象类型,并且每个非空的可以为null的值类型都可隐式转换为与其非关联的对象类型 - 不可空当量。 C#将“派生”定义为“从对象”派生出来的值类型,但是从其基类定义的其他继承类类型来看,它们并不这样做。 – supercat