You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#:无需重写方法,从抽象类调用泛型方法获取继承类型ID

问题:无需重写方法即可获取子类的TypeID?

以下是相关代码实现:

基础类型ID生成类

public static class BaseTypeID
{
    static ulong _id = 1;

    public static ulong NextID => _id++;
}

public static class TypeID<T> where T : class
{
    public static readonly ulong ID = 0;

    static TypeID()
    {
        ID = BaseTypeID.NextID;
    }
}

注册与打印类

public static class Register
{
    public static void PrintType<T>(T passedVar) where T : AbstractType
    {
         Console.WriteLine(TypeID<T>.ID);
    }
}

抽象类与子类

public abstract class AbstractType
{
    public void UseStaticMethod() => Register.PrintType(this);
}

public class InheritingType : AbstractType { }

执行代码与问题

执行以下代码时:

InheritingType myVar = new InheritingType();
myVar.UseStaticMethod();

打印的是AbstractType的ID而非InheritingType的ID——原因是泛型方法PrintType<T>在编译时会将T解析为AbstractType(UseStaticMethod定义在抽象类中,this的编译时类型是AbstractType),而非运行时的实际子类类型。


解决方案(无需子类重写方法)

通过反射获取实例的实际运行时类型,再动态获取对应TypeID<T>的ID值,修改Register类的PrintType方法即可:

public static class Register
{
    public static void PrintType(AbstractType passedVar)
    {
        // 获取实例的真实运行时类型
        Type actualType = passedVar.GetType();
        // 构造对应子类的TypeID<T>泛型类型
        Type typeIdGenericType = typeof(TypeID<>).MakeGenericType(actualType);
        // 读取静态字段ID的值(触发对应TypeID<T>的静态构造函数)
        ulong actualId = (ulong)typeIdGenericType.GetField("ID").GetValue(null);
        Console.WriteLine(actualId);
    }
}

原理说明

  1. GetType()获取实例的真实类型,而非编译时的抽象类类型;
  2. MakeGenericType构造出对应子类的TypeID<InheritingType>类型;
  3. 反射读取静态字段ID时,会自动触发TypeID<InheritingType>的静态构造函数,生成对应的唯一ID。

修改后调用myVar.UseStaticMethod(),会直接打印InheritingType的ID,且无需子类重写任何方法。


内容的提问来源于stack exchange,提问作者ProtoTyPus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 23:51:17