如何将自定义属性获取方法改造为泛型以支持多属性类型
改造为泛型方法实现灵活的属性-属性映射
嘿,这事儿不难搞定!我们可以把原来的方法改成泛型+委托的形式,让它能适配任意自定义属性类型,不管你要提取MongoDBFieldAttribute还是FieldIdentifierAttribute的映射都不在话下。
核心思路
- 用泛型约束限定传入的类型必须是
Attribute子类,确保类型安全 - 传入一个委托函数,用来从目标属性中提取你需要作为字典键的字符串(比如
MongoDBFieldAttribute的Field属性,或者FieldIdentifierAttribute的标识值) - 简化原有的属性过滤逻辑,用
OfType<T>替代手动类型判断,代码更简洁高效
改造后的完整代码
private static Dictionary<string, string> GetAttributePropertyMapping<TAttribute>(Type type, Func<TAttribute, string> keySelector) where TAttribute : Attribute { var propertyMapping = new Dictionary<string, string>(); var properties = type.GetProperties(); foreach (var property in properties) { // 获取当前属性上的指定类型自定义属性,直接过滤出目标类型 var attribute = property.GetCustomAttributes<TAttribute>(inherit: false).FirstOrDefault(); if (attribute == null) continue; // 用委托提取键值,属性名作为字典的值 var key = keySelector(attribute); propertyMapping[key] = property.Name; } return propertyMapping; }
调用示例
假设你的FieldIdentifierAttribute定义如下(如果还没定义,大概是这样):
public class FieldIdentifierAttribute : Attribute { public string Identifier { get; } public FieldIdentifierAttribute(string identifier) { Identifier = identifier; } }
现在你可以轻松获取两种属性的映射:
- 获取
MongoDBFieldAttribute的映射(原逻辑):
var mongoDbMapping = GetAttributePropertyMapping<MongoDBFieldAttribute>(typeof(YourModelType), attr => attr.Field);
- 获取
FieldIdentifierAttribute的映射:
var fieldIdMapping = GetAttributePropertyMapping<FieldIdentifierAttribute>(typeof(YourModelType), attr => attr.Identifier);
额外优化点
- 用
FirstOrDefault()替代遍历多个同类型属性:一般来说一个属性不会重复添加同类型的自定义属性,这样更高效 - 泛型约束
where TAttribute : Attribute确保了只有属性类型能传入,避免无效调用 - 委托
keySelector让方法完全解耦,以后新增其他自定义属性也不用修改方法本身,直接传新的委托即可
内容的提问来源于stack exchange,提问作者Amit Singh
相关产品推荐
相关产品推荐

