C#如何在抽象基类静态方法中获取继承类标注的Attribute属性值
需求实现结论
该需求可以实现,借助C#的反射能力配合合适的语法设计即可完成。
核心问题说明
你原有的写法无法生效的核心原因是:静态方法属于其定义的类(也就是Vehicle),直接通过子类调用VauxhaulAstraSedan.GetVehicleShape()时,运行时感知不到调用的子类类型,自然无法读取子类标记的Attribute。
实现方案
方案1:基类提供泛型静态方法
不需要修改基类的非泛型结构,调用时传入对应子类类型即可:
using System.Reflection; public abstract class Vehicle { public string Brand { get; set; } public string Model { get; set; } public string Colour { get; set; } // 泛型约束只允许传入Vehicle的子类 public static string GetVehicleShape<T>() where T : Vehicle { // 反射读取传入子类的Attribute var attr = typeof(T).GetCustomAttribute<VehicleShapeAttribute>(); return attr?.Shape ?? string.Empty; } }
调用方式:var shape = Vehicle.GetVehicleShape<VauxhaulAstraSedan>();,返回结果为sedan。
方案2:奇异递归模板模式(CRTP)实现子类直接调用
如果希望可以直接通过子类名.GetVehicleShape()的方式调用,不需要手动传泛型参数,可以用CRTP改造基类:
using System.Reflection; // 基类改为泛型,约束T为当前基类的子类 public abstract class Vehicle<T> where T : Vehicle<T> { public string Brand { get; set; } public string Model { get; set; } public string Colour { get; set; } public static string GetVehicleShape() { var attr = typeof(T).GetCustomAttribute<VehicleShapeAttribute>(); return attr?.Shape ?? string.Empty; } } // 子类继承时传入自身作为泛型参数 [VehicleShape("sedan")] public class VauxhaulAstraSedan : Vehicle<VauxhaulAstraSedan> { }
调用方式:var shape = VauxhaulAstraSedan.GetVehicleShape();,直接返回sedan,完全符合你要求的调用形式。
注意事项
- 上述示例用到的
GetCustomAttribute是反射扩展方法,需要引入命名空间System.Reflection。 - 可以根据业务需要增加Attribute不存在时的兜底逻辑,避免返回空值。
内容的提问来源于stack exchange,提问作者pnizzle
相关产品推荐
相关产品推荐

