Извлечение данных атрибута из оформленных свойств - PullRequest
0 голосов
/ 13 марта 2019

Есть ли способ выбрать только properties, которые украшены указанным 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, я сначала фильтрую PropertyInfo[], а затем получаю данные. Есть ли другой, более эффективный способ?

Ответы [ 2 ]

1 голос
/ 13 марта 2019

По какой-то причине синтаксиса 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();
}

Когда запросы становятся еще более сложными, например , этот (полное раскрытие: мой ответ), где необходимо проверить всю сигнатуру метода, простую отслеживание прогрессивной фильтрации и обнаружение фактов, обнаруженных на этом пути. хорошо виден в let предложениях.

1 голос
/ 13 марта 2019

Используя условно-нулевой оператор и выполнив нулевую проверку в качестве последней вещи, вы можете избежать повторного получения пользовательских атрибутов:

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...