判断泛型的值是否为default(T)

博客探讨了在C#中判断泛型类型T的默认值default(T)与某个值是否相等的几种方法,包括尝试使用`==`运算符、`object.Equals`以及`EqualityComparer<T>.Default.Equals`。强调了使用`EqualityComparer<T>.Default.Equals`的适用性和效率,同时提到了反编译工具ILSpy在理解这些实现上的帮助。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

   1: public static bool IsDefault<T>(this T value) 
   2: {
   3:       //...
   4: }
1. ==的问题

    如果用==直接判断(default(T) == value),编译时会提示错误:Error CS0019: 运算符“==”无法应用于“T”和“T”类型的操作数 (CS0019)。

 

2. object.Equals的问题

    object提供了一个静态方法,可用于比较两个对象是否相等:

   1: public static bool Equals(object objA, object objB)
   2: {
   3:     if (objA == objB)
   4:     {
   5:         return true;
   6:     }
   7:     if (objA == null || objB == null)
   8:     {
   9:         return false;
  10:     }
  11:     return objA.Equals(objB);
  12: }

   但是该方法接收的是引用类型的实例,如果传入的是值类型(譬如int、enum、struct等),则会对值类型进行装箱(boxing)。
   

3. EqualityComparer<T>.Default.Equals

    最给力的方法,还是用EqualityComparer<T>.Default.Equals,

   1: public static bool IsDefault<T>(this T value) 
   2: {
   3:      return EqualityComparer<T>.Default.Equals(value, default(T)); 
   4: }

   其实现了一个默认的比较器,可以比较Byte、Nullable<T>、Enum、Object、以及实现了IEquatable<T>接口(譬如int、bool、自定义类型等)的所有类型,可以用ILSpy来查看该类型的具体实现:

   1: private static EqualityComparer<T> defaultComparer;
   2: public static EqualityComparer<T> Default
   3: {
   4:     [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries"), SecuritySafeCritical]
   5:     get
   6:     {
   7:         EqualityComparer<T> equalityComparer = EqualityComparer<T>.defaultComparer;
   8:         if (equalityComparer == null)
   9:         {
  10:             equalityComparer = EqualityComparer<T>.CreateComparer();
  11:             EqualityComparer<T>.defaultComparer = equalityComparer;
  12:         }
  13:         return equalityComparer;
  14:     }
  15: }
  16: [SecuritySafeCritical]
  17: private static EqualityComparer<T> CreateComparer()
  18: {
  19:     RuntimeType runtimeType = (RuntimeType)typeof(T);
  20:     if (runtimeType == typeof(byte))//其实byte也实现了IEquatable<Byte>,不知道为神马要把byte单独提出来???
  21:     {
  22:         return (EqualityComparer<T>)new ();
  23:     }
  24:     if (typeof(IEquatable<T>).IsAssignableFrom(runtimeType))
  25:     {
  26:         return (EqualityComparer<T>)RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(<int>), runtimeType);
  27:     }
  28:     if (runtimeType.IsGenericType && runtimeType.GetGenericTypeDefinition() == typeof(Nullable))
  29:     {
  30:         RuntimeType runtimeType2 = (RuntimeType)runtimeType.GetGenericArguments()[0];
  31:         if (typeof(IEquatable).MakeGenericType(new Type[]
  32:         {
  33:             runtimeType2
  34:         }).IsAssignableFrom(runtimeType2))
  35:         {
  36:             return (EqualityComparer<T>)RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(<int>), runtimeType2);
  37:         }
  38:     }
  39:     if (runtimeType.IsEnum && Enum.GetUnderlyingType(runtimeType) == typeof(int))
  40:     {
  41:         return (EqualityComparer<T>)RuntimeTypeHandle.CreateInstanceForAnotherGenericParameter((RuntimeType)typeof(<int>), runtimeType);
  42:     }
  43:     return new <T>();
  44: }

 

4. ILSpy比JustDecompile强大呀

4.1. ObjectEqualityComparer<T>.Equals方法的比较

image

clip_image001

 

4.2. EqualityComparer<T>.CreateComparer()方法:

image

各种杯具。。。

 

转载于:https://www.cnblogs.com/happyhippy/archive/2011/06/21/2086441.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值