C# 这些可空类型的测试是否等效?
下面是我用来检测我们是否处理可为null的类型的条件:C# 这些可空类型的测试是否等效?,c#,nullable,C#,Nullable,下面是我用来检测我们是否处理可为null的类型的条件: System.Nullable.GetUnderlyingType(itemType) != null 这里是我队友的代码: itemType.IsGenericType && itemType.GetGenericTypeDefinition() == typeof(Nullable<>) itemType.IsGenericType&&itemType.GetGenericTypeDefinition()
System.Nullable.GetUnderlyingType(itemType) != null
这里是我队友的代码:
itemType.IsGenericType && itemType.GetGenericTypeDefinition() == typeof(Nullable<>)
itemType.IsGenericType&&itemType.GetGenericTypeDefinition()==typeof(可空)
事实上,我们没有发现这样的情况:一个返回true
,另一个返回false
(或反之亦然),但这两个代码片段严格等效吗?来自:
如果nullableType参数是封闭的泛型nullable类型,则nullableType参数的类型参数;否则,无效
所以,是的,使用前一个版本是安全的
从GetUnderlineType反编译:
public static Type GetUnderlyingType(Type nullableType)
{
if (nullableType == null)
throw new ArgumentNullException("nullableType");
Type type = (Type) null;
if (nullableType.IsGenericType && !nullableType.IsGenericTypeDefinition && nullableType.GetGenericTypeDefinition() == typeof (Nullable<>))
type = nullableType.GetGenericArguments()[0];
return type;
}
公共静态类型GetUnderlineType(类型nullableType)
{
if(nullableType==null)
抛出新ArgumentNullException(“nullableType”);
Type Type=(Type)null;
if(nullableType.IsGenericType&&!nullableType.IsGenericTypeDefinition&&nullableType.GetGenericTypeDefinition()==typeof(Nullable))
type=nullableType.GetGenericArguments()[0];
返回类型;
}
每当测试类型是否可为空时,我总是使用您发布的第二种方法:
itemType.IsGenericType && itemType.GetGenericTypeDefinition() == typeof(Nullable<>)
itemType.IsGenericType&&itemType.GetGenericTypeDefinition()==typeof(可空)
我对这个没意见
这两个片段并不完全相同。
以下是为每个代码段返回不同值的测试用例:
Type t = typeof(Nullable<>);
bool c1 = Nullable.GetUnderlyingType(t) != null; //false
bool c2 = t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Nullable<>); //true
Type t=typeof(可为空);
bool c1=可为空。GetUnderlineType(t)!=无效//假的
bool c2=t.IsGenericType&&t.GetGenericTypeDefinition()==typeof(可为空)//真的
因此,Nullable.getUnderlineType方法更加安全,因为它的实现已经包含了以下测试用例检查:
public static Type GetUnderlyingType(Type nullableType) {
if (nullableType == null)
throw new ArgumentNullException("nullableType");
Type type = null;
if ((nullableType.IsGenericType && !nullableType.IsGenericTypeDefinition)
&& (nullableType.GetGenericTypeDefinition() == typeof(Nullable<>))) {
type = nullableType.GetGenericArguments()[0];
}
return type;
}
公共静态类型GetUnderlineType(类型nullableType){
if(nullableType==null)
抛出新ArgumentNullException(“nullableType”);
Type=null;
if((nullableType.IsGenericType&&!nullableType.IsGenericTypeDefinition)
&&(nullableType.GetGenericTypeDefinition()==typeof(Nullable))){
type=nullableType.GetGenericArguments()[0];
}
返回类型;
}
您的队友的代码非常好,如MSDN
文档所示(摘录):
使用以下代码确定类型对象是否表示可为空的类型。请记住,如果类型对象是从对GetType的调用返回的,则此代码始终返回false。
if(type.IsGenericType&&type.GetGenericTypeDefinition()==typeof(Nullable)){…}
在以下MSDN链接中解释:
此外,在本次SO QA会议上也有类似的讨论:
dotPeek展示了这一点:
public static Type GetUnderlyingType(Type nullableType)
{
if (nullableType == null)
throw new ArgumentNullException("nullableType");
Type type = (Type) null;
if (nullableType.IsGenericType && !nullableType.IsGenericTypeDefinition && object.ReferenceEquals((object) nullableType.GetGenericTypeDefinition(), (object) typeof (Nullable<>)))
type = nullableType.GetGenericArguments()[0];
return type;
}
公共静态类型GetUnderlineType(类型nullableType)
{
if(nullableType==null)
抛出新ArgumentNullException(“nullableType”);
Type Type=(Type)null;
if(nullableType.IsGenericType&&!nullableType.IsGenericTypeDefinition&&object.ReferenceEquals((对象)nullableType.GetGenericTypeDefinition(),(对象)typeof(Nullable)))
type=nullableType.GetGenericArguments()[0];
返回类型;
}
我看到的唯一区别是,如果
itemType
本身是泛型的,即typeof(List)
,his将失败。您的速度稍慢,因为它必须实际找到底层类型。据我所知,不可为null的类型是一个小的有限列表。通过它们的存在来识别不是更有效吗?@Jeremy:您创建的任何struct
都是不可为空的类型。我无法想象尝试创建一个列表。也许我的问题不清楚,但测试必须返回true和int?a,false和int b。根据我对代码的理解,你的队友首先检查itemType是否为泛型,然后检查泛型类型是否为null。@Gabe,Jeremy对“Nullable Type”使用了另一种解释,而不是OP。Jeremy似乎将其理解为“reference Type”,是的,但它与第二种解释不同吗?请参见编辑后的答案:它是相同的,尽管稍微安全一些,效率稍低一些(除非编译器将其内联)。我们觉得它们都很好,但同时,我们觉得在某种情况下,其中一个不会起作用……是的,从sehe的答案中得到它!反正是Thx
public static Type GetUnderlyingType(Type nullableType)
{
if (nullableType == null)
throw new ArgumentNullException("nullableType");
Type type = (Type) null;
if (nullableType.IsGenericType && !nullableType.IsGenericTypeDefinition && object.ReferenceEquals((object) nullableType.GetGenericTypeDefinition(), (object) typeof (Nullable<>)))
type = nullableType.GetGenericArguments()[0];
return type;
}