如何在泛型方法中仅传入Adapter子类类型,检查其配置类特性?
解决方案
你可以通过泛型约束+反射实现需求:仅传入单个Adapter子类类型作为泛型参数,同时确保该类型是AdapterBase<T>的派生类,最终检查对应配置类是否存在MyCustomAttribute。
完整实现步骤与代码
1. 基础类型定义(与你的代码一致)
// 自定义特性 public class MyCustomAttribute : Attribute { public string Name { get; } public MyCustomAttribute(string name) => Name = name; } // 抽象泛型基类 public abstract class AdapterBase<T> { public string AdapterName { get; set; } public T? Configuration { get; set; } } // 配置类(带自定义特性) [MyCustomAttribute("Foo")] public class FooConfiguration { } [MyCustomAttribute("bar")] public class BarConfiguration { } // Adapter子类 public class FooAdapter : AdapterBase<FooConfiguration> { } public class BarAdapter : AdapterBase<BarConfiguration> { }
2. 核心检查方法
public static bool HasCustomConfigurationAttribute<T>() where T : AdapterBase<object> // 用object作为占位约束,确保T属于AdapterBase派生体系 { // 获取T的基类(即AdapterBase<U>) var baseType = typeof(T).BaseType; if (baseType == null || !baseType.IsGenericType || baseType.GetGenericTypeDefinition() != typeof(AdapterBase<>)) { throw new ArgumentException($"类型 {typeof(T).Name} 必须继承自 AdapterBase<T>"); } // 提取配置类的类型U var configType = baseType.GetGenericArguments()[0]; // 检查配置类是否存在目标特性 return Attribute.IsDefined(configType, typeof(MyCustomAttribute)); }
3. 调用示例
// 检查FooAdapter对应的配置类特性 bool fooHasAttr = HasCustomConfigurationAttribute<FooAdapter>(); // 返回true // 检查BarAdapter对应的配置类特性 bool barHasAttr = HasCustomConfigurationAttribute<BarAdapter>(); // 返回true
严谨性优化(可选)
如果觉得where T : AdapterBase<object>的约束不够精准,可以改用纯反射验证类型合法性,同时保留单个泛型参数:
public static bool HasCustomConfigurationAttribute<T>() where T : class { var adapterType = typeof(T); // 验证T是否是AdapterBase<>的派生类 bool isAdapterDerived = adapterType.IsSubclassOf(typeof(AdapterBase<>).MakeGenericType(typeof(object))) || adapterType.GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(AdapterBase<>)); if (!isAdapterDerived) { throw new ArgumentException($"类型 {adapterType.Name} 必须继承自 AdapterBase<T>"); } // 后续逻辑与之前一致 var baseType = adapterType.BaseType; var configType = baseType.GetGenericArguments()[0]; return Attribute.IsDefined(configType, typeof(MyCustomAttribute)); }
这种方式无需实例化Adapter对象,仅通过类型信息即可完成检查,同时避免了传入不匹配类型的风险。
内容的提问来源于stack exchange,提问作者Viktor Pagels
相关产品推荐
相关产品推荐

