如果有以下方法:
static void DoSomethingWithTwoNullables(Nullable<int> a, Nullable<int> b)
{
Console.WriteLine("Param a is Nullable<int>: " + (a is Nullable<int>));
Console.WriteLine("Param a is int : " + (a is int));
Console.WriteLine("Param b is Nullable<int>: " + (b is Nullable<int>));
Console.WriteLine("Param b is int : " + (b is int));
}
当我使用null作为参数调用此方法时,类型检查将为此参数返回false。例如这段代码
DoSomethingWithTwoNullables(5, new Nullable<int>());
导致此输出:
Param a is Nullable<int>: True
Param a is int : True
Param b is Nullable<int>: False
Param b is int : False
使用Nullable并传递null时,有没有办法保留类型信息?我知道在这个例子中检查类型是没用的,但它说明了问题。在我的项目中,我将参数传递给另一个采用params object[]
数组的方法,并尝试识别对象的类型。此方法需要对Nullable<int>
和Nullable<long>
执行不同的操作。
答案 0 :(得分:5)
直接找到根本问题,不,你不能这样做。 null Nullable<int>
具有与null Nullable<long>
完全相同的盒装表示,或者实际上是'normal'null。没有办法告诉它是什么类型的null,因为它的底层表示只是全零。有关详细信息,请参阅Boxing Nullable Types。
答案 1 :(得分:3)
从概念上讲,new Nullable<int>
是 null
。
如果我们概括,忘记Nullable<T>
:
string s = null;
bool b = s is string;
我们得到false
。 false
是对null
值进行类型检查的预期值。
答案 2 :(得分:1)
您可以尝试使用Reflection来实现此目的。 Relevant article here.
答案 3 :(得分:0)
不幸的是,null
没有指向任何特定的内存位置,因此没有可以与之关联的元数据来查找类型。因此,您无法获得有关变量的任何其他信息。
答案 4 :(得分:0)
除非我误解了这个问题,否则您可以使用GetType()
获取该类型。例如,
int? myNullableInt = null;
Console.WriteLine(myNullableInt.GetValueOrDefault().GetType());
如果myNullableInt
为null,则返回默认值。检查此返回值的类型,在这种情况下,它将返回System.Int32
。您可以对返回的类型进行If..else
/ Switch
检查以执行相关操作。
(int?
与Nullable<int>
)
答案 5 :(得分:0)
你不能这样做,你也不想这样做。由于Nullable<T>
是结构,因此此类型的值类型变量具有编译时所需的所有类型信息。只需使用typeof
运算符。
另一方面,您可能有一个Nullable实例,其类型在编译时是您不知道的。那必须是一个静态类型为object
或其他引用类型的变量。不管怎么说,因为Nullable<T>
值框装入了T
盒装值,所以没有装箱Nullable<T>
这样的东西。那个类型只需要检查的实例T
。
这就是为is int
和is Nullable<int>
获得相同结果的原因。由于没有装箱int
,因此无法区分盒装int?
和盒装int?
。
有关详细信息,请参阅Nulls not missing anymore。
答案 6 :(得分:0)
正如已经指出null
没有类型。要确定某些内容是int?
还是long?
,您需要使用反射来获取有关存储该类型的内容的信息。下面是一些代码,您可以将它们用作灵感(不知道您尝试实现代码的确切内容有点奇怪):
class Pair<T> where T : struct {
public Pair(T? a, T? b) {
A = a;
B = b;
}
public T? A { get; private set; }
public T? B { get; private set; }
}
void DoSomething<T>(Pair<T> pair) where T : struct {
DoMore(pair);
}
void DoMore(params object[] args) {
Console.WriteLine("Do more");
var nullableIntPairs = args.Where(IsNullableIntPair);
foreach (Pair<int> pair in nullableIntPairs) {
Console.WriteLine(pair.A);
Console.WriteLine(pair.B);
}
}
bool IsNullableIntPair(object arg) {
var type = arg.GetType();
return type.IsGenericType
&& type.GetGenericTypeDefinition() == typeof(Pair<>)
&& type.GetGenericArguments()[0] == typeof(int);
}
如果执行以下代码
DoSomething(new Pair<int>(5, new int?()));
DoSomething(new Pair<long>(new long?(), 6L));
你得到以下输出:
Do more 5 null Do more
答案 7 :(得分:0)
您可以使用typeof:
a == typeof(Nullable<int>) //true
a == typeof(int) //false