[英]Extracting attribute data from decorated properties
Is there any method to select only the properties
that are decorated with a specified Attribute
and extract the Attribute
data ...all in one pass? 有没有只选择任何方法properties
与某个特定的装饰Attribute
和提取Attribute
数据......都在一个通?
Currently i am first doing a PropertyInfo
filtering and then i am getting the Attribute data: 目前,我首先执行PropertyInfo
过滤,然后获取属性数据:
Attribute data: 属性数据:
public class Weight
{
public string Name { get; set; }
public double Value { get; set; }
public Weight(string Name,double Value) {
this.Name = Name;
this.Value = Value;
}
}
Attribute: 属性:
[AttributeUsage(AttributeTargets.Property)]
public class WeightAttribute : Attribute
{
public WeightAttribute(double val,[CallerMemberName]string Name=null)
{
this.Weight = new Weight(Name, val);
}
public Weight Weight { get; set; }
}
Extractor: 提取器:
private static IReadOnlyList<Weight> ExtractWeights(Type type)
{
var properties = type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly)
.Where(x => x.GetCustomAttribute<WeightAttribute>() != null);
var weights = properties
.Select(x => x.GetCustomAttribute<WeightAttribute>().Weight)
.ToArray();
return weights;
}
As you can see in my Extractor
method i am first filtering the PropertyInfo[]
and then getting the data's.Is there any other more efficient way? 如您在我的Extractor
方法中所看到的,我首先过滤PropertyInfo[]
,然后获取数据。还有其他更有效的方法吗?
By using the null-conditional operator and doing the null check as last thing you can avoid getting the custom attributes again: 通过使用空条件运算符并最后进行空检查,可以避免再次获取自定义属性:
private static IReadOnlyList<Weight> ExtractWeights(Type type)
{
return type
.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly)
.Select(x => x.GetCustomAttribute<WeightAttribute>()?.Weight)
.Where(x => x!= null)
.ToArray();
}
Full example: https://dotnetfiddle.net/fbp50c 完整示例: https : //dotnetfiddle.net/fbp50c
For some reason, LINQ syntax seems to be avoided when it's actually quite useful and makes the intent ridiculously clear. 出于某些原因,当LINQ语法实际上非常有用并且意图很明显时,似乎应该避免使用它。
Rewritten with LINQ syntax, the following applies @DavidG's excellent point. 用LINQ语法重写,以下内容适用@DavidG的优点。
private static IReadOnlyList<Weight> ExtractWeights(Type type)
{
return (from p in type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly)
let attr = p.GetCustomAttribute<WeightAttribute>()
where attr != null
select attr.Weight).ToArray();
}
When queries get even more complex, like this one (full disclosure: my answer) where the entire method signature needed to be tested, the progressive filtering is easy to follow and facts discovered along the way are highly visible in let
clauses. 当查询变得更加复杂时,就像这样的 (完整披露:我的回答),其中需要测试整个方法签名,渐进式过滤很容易遵循,并且沿途发现的事实在let
子句中非常明显。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.