[英]Type checking on Nullable<int>
If have the following method: 如果有以下方法:
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));
}
When i call this method with null as a parameter, the type check returns false for this parameter. 当我使用null作为参数调用此方法时,类型检查将为此参数返回false。 For example this code
例如这段代码
DoSomethingWithTwoNullables(5, new Nullable<int>());
results in this output: 结果输出:
Param a is Nullable<int>: True
Param a is int : True
Param b is Nullable<int>: False
Param b is int : False
Is there any way to preserve the type information when using a Nullable and passing null? 有没有办法在使用Nullable并传递null时保留类型信息? I know that checking the type in this example is useless, but it illustrates the problem.
我知道在这个例子中检查类型是没用的,但它说明了问题。 In my project, I pass the parameters to another method that takes a
params object[]
array and tries to identify the type of the objects. 在我的项目中,我将参数传递给另一个采用
params object[]
数组的方法,并尝试识别对象的类型。 This method needs to do different things for Nullable<int>
and Nullable<long>
. 这个方法需要为
Nullable<int>
和Nullable<long>
做不同的事情。
Going straight to the underlying problem, no, you can't do this. 直接找到潜在的问题,不,你不能这样做。 A null
Nullable<int>
has exactly the same boxed representation as a null Nullable<long>
, or indeed a 'normal' null. 空
Nullable<int>
具有完全相同的盒装表示作为一个空Nullable<long>
,或者确实是一个“正常”的空值。 There is no way to tell what 'type' of null it is, since its underlying representation is simply all-zeros. 没有办法告诉它是什么类型的null,因为它的底层表示只是全零。 See Boxing Nullable Types for more details.
有关详细信息,请参阅Boxing Nullable Types 。
conceptually, new Nullable<int>
is null
. 从概念上讲,
new Nullable<int>
为 null
。
If we generalise, forgetting about Nullable<T>
: 如果我们概括,忘记
Nullable<T>
:
string s = null;
bool b = s is string;
we get false
. 我们
false
。 false
is the expected value for a type-check on a null
value. false
是对null
值进行类型检查的预期值。
You can try using Reflection to achieve this. 您可以尝试使用Reflection来实现此目的。 Relevant article here.
相关文章在这里。
Unfortunately, null
does not point to any specific memory location, and thus there is no metadata that you can associate with it to lookup the type. 不幸的是,
null
并不指向任何特定的内存位置,因此没有可以与之关联的元数据来查找类型。 Thus, you cannot gain any additional information about the variable. 因此,您无法获得有关变量的任何其他信息。
Unless I'm misunderstanding the question, you can get the type using GetType()
. 除非我误解了这个问题,否则你可以使用
GetType()
来获取类型。 For example, 例如,
int? myNullableInt = null;
Console.WriteLine(myNullableInt.GetValueOrDefault().GetType());
If myNullableInt
is null, a default value will be returned. 如果
myNullableInt
为null,则返回默认值。 Check the type of this returned value and, in this case, it will return System.Int32
. 检查此返回值的类型,在这种情况下,它将返回
System.Int32
。 You can do an If..else
/ Switch
check on the returned type to perform the relevant action. 您可以对返回的类型执行
If..else
/ Switch
检查以执行相关操作。
( int?
is the same as Nullable<int>
) (
int?
与Nullable<int>
相同)
You can't do this, nor should you want to. 你不能这样做,你也不应该这样做。 Since
Nullable<T>
is a struct, value-type variables of this type have all the type information you need at compile time. 由于
Nullable<T>
是一个结构,因此这种类型的值类型变量具有编译时所需的所有类型信息。 Just use the typeof
operator. 只需使用
typeof
运算符即可。
On the other hand, you might have a Nullable instance whose type you don't know at compile time. 另一方面,您可能有一个Nullable实例,其类型在编译时是您不知道的。 That would have to be a variable whose static type is
object
or some other reference type. 那必须是一个变量,其静态类型是
object
或其他一些引用类型。 Howver, because a Nullable<T>
value boxes to a boxed T
value, there's no such thing as a boxed Nullable<T>
. 但是,因为
Nullable<T>
值框到盒装T
值,所以没有盒装Nullable<T>
这样的东西。 That instance whose type your checking will just be a T
. 那个类型的实例,你的检查只是一个
T
This is why you get the same result for is int
and is Nullable<int>
. 这就是为什么你得到与
is int
相同的结果并且is Nullable<int>
。 There's no way to distinguish between a boxed int
and a boxed int?
有没有办法区分盒装
int
和盒装int?
, because there is no boxed int?
,因为没有盒装
int?
. 。
See Nulls not missing anymore for details. 有关详细信息,请参阅Nulls不再缺失 。
As it has already been pointed out null
has no type. 正如已经指出的那样,
null
没有类型。 To figure out if something is int?
要弄清楚是否有东西
int?
vs long?
vs
long?
you need to use reflection to get information about something storing the type. 你需要使用反射来获取有关存储类型的信息。 Here is some code that you may be able to use as inspiration (not knowing exactly what you try to achieve the code is a bit weird):
下面是一些代码,您可以将它们用作灵感(不知道您尝试实现代码的确切内容有点奇怪):
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);
}
If you execute the following code 如果您执行以下代码
DoSomething(new Pair<int>(5, new int?()));
DoSomething(new Pair<long>(new long?(), 6L));
you get the following output: 你得到以下输出:
Do more 5 null Do more
You can use typeof : 你可以使用typeof:
a == typeof(Nullable<int>) //true
a == typeof(int) //false
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.