C#获取自定义属性扩展方法

Posted

技术标签:

【中文标题】C#获取自定义属性扩展方法【英文标题】:C# get custom attribute extension method 【发布时间】:2022-01-13 05:25:06 【问题描述】:

有人可以帮我为 newtonsoft.json 和 mongodb 的自定义属性创建扩展方法吗?

假设我有以下课程:

public class Foo

    [BsonElement("MyCustomDbName")]
    [JsonProperty("MyCustomJsonName")]
    public string Name  get; set; 

如何创建扩展方法来获取以下内容:

var myFoo = new Foo()Name="";
var mongoDbElementName = myFoo.Name.GetMongoDbElementName(); // should return 'MyCustomDbName'
var jsonPropertyName = myFoo.Name.GetJsonPropertyName(); // should return 'MyCustomJsonName'

或直接使用类本身:

var mongoDbElementName = Foo.Name.GetMongoDbElementName(); // should return 'MyCustomDbName'
var jsonPropertyName = Foo.Name.GetJsonPropertyName(); // should return 'MyCustomJsonName'

我试过这样的东西:

public static string GetMongoDbElementName(this Type modelType, PropertyInfo property)

    return (modelType.GetProperty(nameof(property)) ?? throw new InvalidOperationException()).GetCustomAttribute<BsonElementAttribute>()?.ElementName;

但是有没有办法不带参数呢?

提前谢谢

【问题讨论】:

【参考方案1】:

您不能直接在属性上执行此操作;您需要将扩展​​方法应用于类并使用表达式来选择属性:

public static string GetMongoDbElementName<T>(
    this T obj,
    Expression<Func<T, object>> propertySelector)

    var memberExpression = propertySelector.Body as MemberExpression;
    var memberName = memberExpression?.Member.Name
        ?? throw new InvalidOperationException();

    var bsonAttribute = obj
        .GetType()
        .GetProperty(memberName)
        .GetCustomAttribute<BsonElementAttribute>();

    return bsonAttribute?.ElementName;

用法:

var mongoDbElementName = myFoo.GetMongoDbElementName(x => x.Name);

您可能还想更新代码以防止其他成员被选中(例如方法),可以这样做:

var property = obj
    .GetType()
    .GetProperty(memberName)
    ?? throw new InvalidOperationException($"memberName is not a property");
 
var bsonAttribute = property
    .GetCustomAttribute<BsonElementAttribute>();

【讨论】:

THX,很好的解决方案!!!【参考方案2】:

您可以使用反射获取属性及其值:

public static string GetBsonElementName(this Foo foo)

    var bsonElementAttribute =
        typeof(Foo)
        .GetProperty(nameof(Foo.Name))
        .GetCustomAttribute<BsonElementAttribute>();

    return bsonElementAttribute.ElementName;


public static string GetJsonPropertyName(this Foo foo)

    var jsonPropertyAttribute =
        typeof(Foo)
        .GetProperty(nameof(Foo.Name))
        .GetCustomAttribute<JsonPropertyAttribute>();

    return jsonPropertyAttribute.PropertyName;

你可以这样使用它:

var foo = new Foo();
var bsonElementName = foo.GetBsonElementName();
var jsonPropertyName = foo.GetJsonPropertyName();

【讨论】:

这不太可能有用,因为它被硬编码为Foo.Name 还有,BsonName?是什么

以上是关于C#获取自定义属性扩展方法的主要内容,如果未能解决你的问题,请参考以下文章

Android Gradle 插件Gradle 自定义 Plugin 插件 ④ ( 为自定义 Gradle 插件的扩展配置扩展 | 在自定义插件中获取扩展属性 )

如何通过传入枚举值和属性类型来获取枚举的自定义属性?

如何用jquery获取页面中的自定义标签

flowable入门(四)增加自定义类型的扩展属性

如何在 C# 中创建自定义属性

H5自定义属性的规定和添加获取自定义属性的方法