(021)C# 判断类与泛型类的关系

泛型类参数化后的基类问题

泛型只是一种代码实现技术,在编译的过程中,会根据泛型的参数类型,生成一个对于的类。比如 :

public abstract class PacketHandler<T> : IHandler
{
     public abstract string Identity();
     
     public virtual string HandlerKey()
     {
         return Identity();
     }

     public abstract void Handler(object sender, T packet);

     /// <summary>
     /// 委托调用,将包转换成具体的子类。 
     /// </summary>
     /// <param name="sender"></param>
     /// <param name="packet"></param>
     public void Delegate(object sender, EventArgs packet)
     {
         if (packet is T t)
         {
             Handler(sender, t);
             return;
         }
         Debug.WriteLine($"not match packet type: {typeof(T).Name}");
     }
 }
 
 public class HelloPacketHandler: PacketHandler<HelloPacket>
 {
      public override string Identity()
      {
          return PacketHandlerName.Hello;
      }

      public override void Handler(object sender, HelloPacket packet)
      {
          Console.WriteLine(nameof(HelloPacketHandler));
      }
  }

断点查看 HelloPacketHandlerBaseType:
在这里插入图片描述
判断 HelloPacketHandler 类是否为 PacketHandler 泛型类参数实例化的类,不能直接用 :

// HelloPacket extends Packet
typeof(HelloPacketHandler) == typeof(PacketHandler<Packet>)

判断运行类和泛型类的关系

public class TypeUtils
 {
      /// <summary>
      /// 判断A类是否为B类的直接派生类或者A类是否为B泛型类的直接派生类。
      /// </summary>
      /// <param name="aChildBaseClassType"></param>
      /// <param name="bParentClass"></param>
      /// <returns></returns>
      public static bool isBaseTypeOfClass(Type aChildBaseClassType, Type bParentClass)
      {
          if (bParentClass.GenericTypeArguments.Length != aChildBaseClassType.GenericTypeArguments.Length)
          {
              return false;
          }
          if (bParentClass.GenericTypeArguments.Length == 0)
          {
              return aChildBaseClassType == bParentClass;
          }
          for (int i = 0; i < bParentClass.GenericTypeArguments.Length; i++)
          {
              if (!isBaseTypeOfClass(aChildBaseClassType.GenericTypeArguments[i].BaseType, bParentClass.GenericTypeArguments[i]))
              {
                  return false;
              }
          }
          return true;
      }
  }

代码测试

[Test]
public void TestIsBaseTypeOfClass()
{
    Assert.True(TypeUtils.isBaseTypeOfClass(typeof(HelloPacketHandler).BaseType, typeof(PacketHandler<Packet>))); 
    
    Assert.False(TypeUtils.isBaseTypeOfClass(typeof(ChildHelloPacketHandler).BaseType, typeof(PacketHandler<Packet>))); 
    
    Assert.True(TypeUtils.isBaseTypeOfClass(typeof(ChildHelloPacketHandler).BaseType, typeof(HelloPacketHandler)));  
    
    Assert.False(TypeUtils.isBaseTypeOfClass(typeof(HelloPacketHandler).BaseType, typeof(PacketHandler<EventArgs>))); 
}

测试代码下载

PacketExample,提取码:r4zv

[1] 创建单元测试

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值