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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 15:15:02