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); } }
原理说明
GetType()获取实例的真实类型,而非编译时的抽象类类型;MakeGenericType构造出对应子类的TypeID<InheritingType>类型;- 反射读取静态字段
ID时,会自动触发TypeID<InheritingType>的静态构造函数,生成对应的唯一ID。
修改后调用myVar.UseStaticMethod(),会直接打印InheritingType的ID,且无需子类重写任何方法。
内容的提问来源于stack exchange,提问作者ProtoTyPus
相关产品推荐
相关产品推荐

