【问题标题】:C# get custom attribute extension methodC#获取自定义属性扩展方法
【发布时间】: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;
}

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

提前谢谢

【问题讨论】:

    标签: c# mongodb json.net


    【解决方案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?是什么
    猜你喜欢
    • 2013-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多