从装饰的属性中提取属性数据

时间:2019-03-13 13:36:01

标签: c# reflection .net-core attributes

是否有任何方法可以只选择装饰有指定properties的{​​{1}}并提取Attribute数据…全部通过?

当前,我首先进行Attribute过滤,然后获取属性数据:

属性数据:

PropertyInfo

属性:

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;
    }
}

提取器:

[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; }
}

您可以在我的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; } 方法中看到,我首先过滤Extractor然后获取数据。还有其他更有效的方法吗?

2 个答案:

答案 0 :(得分:1)

通过使用null-conditional operator并最后进行空检查,可以避免再次获取自定义属性:

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();
}

完整示例:https://dotnetfiddle.net/fbp50c

答案 1 :(得分:1)

由于某种原因,似乎可以避免使用LINQ语法,但实际上却非常有用,并且使意图很明显。

用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();
}

当查询变得更加复杂时,例如this one(完整披露:我的答案),其中需要测试整个方法签名,则渐进式过滤很容易遵循,并且沿途发现的事实在其中非常明显。 let子句。