Получить значение свойства из объекта коллекции - PullRequest
0 голосов
/ 17 июня 2020

У меня есть 2 класса со следующими определениями:

public class Calculation
{
    public int Id;
    public ICollection<CalculationDetails> CalculationDetails;
}

public class CalculationDetails
{
    public int Id;
    public decimal? Rate;
    public decimal? Amount;
    public int ChargeId;
    public string Category;
    public int UnitId;
}

Мне нужен общий c метод расширения для ICollection, который примет имя свойства, CalculId и категорию и вернет значение соответствующего свойства после фильтрации списка. Примерно так:

public static T GetCalculationDetailsValue(this ICollection<CalculationDetails> freightCalculationDetails, string propertyName, int calculationId, string category)
{
    // using reflection or any suitable method returns the value as per the specified property name 
    // in the parameter.
}

Я видел этот пример.

Ответы [ 2 ]

2 голосов
/ 17 июня 2020

Если propertyName не обязательно должна быть строкой, вы можете вместо этого использовать лямбда-выражение для извлечения правого поля. C# строго типизирован, поэтому это лучшее решение, которое я могу найти, если вы хотите, чтобы свойства в PriceCalculationDetails были разных типов.

    public static T GetTheThing<T>(this ICollection<CalculationDetails> calculationDetails, Func<CalculationDetails, T> propertyExtractor, int calculationId, string category)
    {
        var matchingCalculationDetails = calculationDetails.First();    // Insert your preferred logic to find the right one here.

        return propertyExtractor(matchingCalculationDetails);
    }

Затем вы можете вызвать этот метод, выполнив

decimal rate = someCalculationDetailsCollection.GetTheThing(x => x.Rate, 0, "category0")

Это похоже на прямое использование LINQ:

someCalculationDetailsCollection
    .Where(x => x.Id == 0 && x.Category == "category0")
    .Select(x => x.Rate)
1 голос
/ 17 июня 2020

Вот как сделать то, о чем вы просили:

public static class Extensions
{
    public static object GetCalculationDetailsValue(this ICollection<CalculationDetails> freightCalculationDetails, string propertyName, int calculationId, string category)
    {
        var calculationDetails = freightCalculationDetails.FirstOrDefault(x => x.Id == calculationId && x.Category == category);

        if(calculationDetails is null)
        {
            return null;
        }

        return typeof(CalculationDetails).GetProperty(propertyName).GetValue(calculationDetails);
    }
}

public class CalculationDetails
{
    public int Id;
    public decimal? Rate;
    public decimal? Amount;
    public int ChargeId;
    public string Category;
    public int UnitId;
}

В любом случае вам следует избегать такого подхода, он использует рефлексию, которая очень медленная и ее можно избежать в большинстве ситуаций.

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