C#获取自定义属性扩展方法
C# get custom attribute extension method
有人可以帮我为 newtonsoft.json 和 mongodb 的自定义属性创建扩展方法吗?
假设我关注了 class:
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'
或直接使用 class 本身:
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;
}
但是有没有不用参数的方法呢?
提前致谢
您不能直接在 属性 上这样做;您需要将扩展方法应用于 class 并使用表达式 select 属性:
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);
您可能还想更新代码以防止其他成员被 selected(例如方法),可以这样做:
var property = obj
.GetType()
.GetProperty(memberName)
?? throw new InvalidOperationException($"{memberName} is not a property");
var bsonAttribute = property
.GetCustomAttribute<BsonElementAttribute>();
您可以使用反射获取属性及其值:
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();
有人可以帮我为 newtonsoft.json 和 mongodb 的自定义属性创建扩展方法吗?
假设我关注了 class:
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'
或直接使用 class 本身:
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;
}
但是有没有不用参数的方法呢?
提前致谢
您不能直接在 属性 上这样做;您需要将扩展方法应用于 class 并使用表达式 select 属性:
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);
您可能还想更新代码以防止其他成员被 selected(例如方法),可以这样做:
var property = obj
.GetType()
.GetProperty(memberName)
?? throw new InvalidOperationException($"{memberName} is not a property");
var bsonAttribute = property
.GetCustomAttribute<BsonElementAttribute>();
您可以使用反射获取属性及其值:
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();