C# 可为空<;长期>;不可为空<;长期>;在龙的任务之后
我在原语上有一个意外的可为null的行为 我的测试代码:C# 可为空<;长期>;不可为空<;长期>;在龙的任务之后,c#,.net,nullable,C#,.net,Nullable,我在原语上有一个意外的可为null的行为 我的测试代码: Nullable<long> value = long.Parse("5"); Type type = value.GetType(); // at this Point type is System.Int64 and not Nullable<System.Int64> Nullable value=long.Parse(“5”); Type Type=value.GetType(); /
Nullable<long> value = long.Parse("5");
Type type = value.GetType();
// at this Point type is System.Int64 and not Nullable<System.Int64>
Nullable value=long.Parse(“5”);
Type Type=value.GetType();
//此时,类型为System.Int64,不可为null
是否有可能,
值
保持为可空
,并且不会转换为常规的长
?否。您已将其分配给长
变量
调用GetType()
时,此函数在System.Object
上定义。因此,要调用它,我们必须将该值装箱
您可以通过查看为GetType()调用生成的MSIL指令来查看这一点:
box系统。可为空
调用System.Object.GetType
因此,当它被装箱时,它实际上会将long?
推到堆栈上,装箱只会给我们一个装箱的long
因此,在可为null的情况下,结果值是基类型(请参见和)
在本例中,无论如何都没有理由调用GetType
,因为当您查看long时,我们知道它是一个long?
。Parse
返回long
,而不是long?
public static long Parse (string s);
当然,您可以将转换为长?
,但这不会改变该语句
long a = long.Parse("5");
Nullable<long> n = a; // convert to long?
对变量调用GetType
将为您提供运行时类型,而不是编译时类型。当Parse
在运行时返回一个long
时,GetType
肯定也会返回。long.Parse
始终返回一个long
,而不是long?
。所以答案肯定是:不。为什么要使用long?
?嗯,long.Parse
返回long
,而不是long?
——因此变量的实际内容是long
。这就是说:如果您的值是null
,那么无论如何,您不能对其调用.GetType()
。这个值的强类型为null。我希望在声明之后使用一个可为null的值,而不是一个很长的值。查看文档了解如何识别可为null的值类型。这是错误的。它被分配给一个long?
@Charlieface当然,但是在我们可以分配它之前,我们必须转换它。好的,但是你没有解释为什么GetType
返回long
而不是long?
@Charlieface查看我的最后一句话…@ArndtBieberstein是的,GetType
会一直给你值的类型,无论您在编译时如何声明它。当您调用GetType()时,此函数是在System.Object上定义的。因此,要调用它,我们必须将该值装箱。这是非直观的,即使我完全理解它,并且我理解它为什么会发生,但它仍然是非直观的:-)100%同意,Nullable
(以及通常的valuetype)语义留下了需要的内容“因为我们知道它很长?”不,它不是长?
-至少在运行时不是这样,在赋值给long?
变量之后,它是一个long?
变量。然后将其装箱,将其转换回装箱的long
5
不是long?
,但它是可分配给它的。因此,不是,该值仍然是一个长的
。声明变量的方式和它在运行时所包含的内容之间有着巨大的差异,*这就是GetType
将要介绍的内容。
long a = long.Parse("Hello"); //throws FormatException