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

如何将自定义属性获取方法改造为泛型以支持多属性类型

改造为泛型方法实现灵活的属性-属性映射

嘿,这事儿不难搞定!我们可以把原来的方法改成泛型+委托的形式,让它能适配任意自定义属性类型,不管你要提取MongoDBFieldAttribute还是FieldIdentifierAttribute的映射都不在话下。

核心思路

  1. 用泛型约束限定传入的类型必须是Attribute子类,确保类型安全
  2. 传入一个委托函数,用来从目标属性中提取你需要作为字典键的字符串(比如MongoDBFieldAttribute的Field属性,或者FieldIdentifierAttribute的标识值)
  3. 简化原有的属性过滤逻辑,用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;
    }
}

现在你可以轻松获取两种属性的映射:

  1. 获取MongoDBFieldAttribute的映射(原逻辑):
var mongoDbMapping = GetAttributePropertyMapping<MongoDBFieldAttribute>(typeof(YourModelType), attr => attr.Field);
  1. 获取FieldIdentifierAttribute的映射:
var fieldIdMapping = GetAttributePropertyMapping<FieldIdentifierAttribute>(typeof(YourModelType), attr => attr.Identifier);

额外优化点

  • 用FirstOrDefault()替代遍历多个同类型属性:一般来说一个属性不会重复添加同类型的自定义属性,这样更高效
  • 泛型约束where TAttribute : Attribute确保了只有属性类型能传入,避免无效调用
  • 委托keySelector让方法完全解耦,以后新增其他自定义属性也不用修改方法本身,直接传新的委托即可

内容的提问来源于stack exchange,提问作者Amit Singh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:11:18