C# 如何通过泛型获取实现接口类的静态属性
问题本质
你当前代码无法运行的核心原因是:C# 11之前不支持接口定义可被实现类重写的静态成员;即便是C# 11及以上版本,也需要将接口的静态成员显式标记为abstract,才能在泛型约束下通过类型参数直接访问静态成员。
方案1:C# 11及以上版本(推荐,编译时检查+无额外性能开销)
直接将接口的静态属性标记为static abstract即可满足你的需求,不需要修改实现类和调用逻辑:
public interface IHasName { // 新增abstract关键字,要求所有实现类必须提供对应的静态属性 static abstract string Name { get; } } // 泛型方法无需改动 public static string GetName<T>() where T : IHasName { return T.Name; } // 实现类和调用逻辑和你期望的完全一致 public class Model: IHasName { public static string Name => "Niek"; } // 调用方式 var name = GetName<Model>();
该方案所有检查都在编译期完成,没有运行时额外开销,是最优实现。
方案2:C# 10及以下版本兼容方案(反射实现)
如果你的项目无法升级到C# 11,可以通过反射读取泛型类型的静态属性实现需求:
// 可保留IHasName作为标记接口,用于约束泛型传入范围 public interface IHasName { } public static string GetName<T>() where T : IHasName { // 反射查找T类型的公共静态Name属性 var nameProp = typeof(T).GetProperty( "Name", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static ); if (nameProp == null) { throw new InvalidOperationException($"类型{typeof(T).FullName}未实现公共静态属性Name"); } return (string)nameProp.GetValue(null); } // 实现类和调用逻辑同样不需要修改 public class Model: IHasName { public static string Name => "Niek"; } var name = GetName<Model>();
该方案兼容低版本C#,但存在运行时反射开销,且静态属性的存在性只能在运行时检查。
内容的提问来源于stack exchange,提问作者niek tuytel
相关产品推荐
相关产品推荐

