Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/291.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从集合对象获取属性值_C#_.net_Generics - Fatal编程技术网

C# 从集合对象获取属性值

C# 从集合对象获取属性值,c#,.net,generics,C#,.net,Generics,我有两个具有以下定义的类: public class Calculation { public int Id; public ICollection<CalculationDetails> CalculationDetails; } public class CalculationDetails { public int Id; public decimal? Rate; public decimal? Amount; public

我有两个具有以下定义的类:

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;
}
公共类计算
{
公共int Id;
公共ICollection计算详细信息;
}
公共类计算详细信息
{
公共int Id;
公共小数利率;
公共小数?金额;
公共ID;
公共字符串类别;
公共国际联合会;
}
我想要一个ICollection的通用扩展方法,该方法将采用属性名称、calculationId和类别,并在过滤列表后返回相应属性的值。 大概是这样的:

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.
}
public static T getCalculationDetails值(此ICollection-freightCalculationDetails、字符串属性名称、int-calculationId、字符串类别)
{
//使用反射或任何合适的方法将根据指定的属性名返回值
//在参数中。
}

我看到了一个例子。

这是如何实现您的要求:

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;
}
公共静态类扩展
{
公共静态对象GetCalculationDetailsValue(此ICollection-freightCalculationDetails,字符串属性名称,int-calculationId,字符串类别)
{
var calculationDetails=freightCalculationDetails.FirstOrDefault(x=>x.Id==calculationId&&x.Category==Category);
如果(calculationDetails为空)
{
返回null;
}
返回typeof(CalculationDetails).GetProperty(propertyName).GetValue(CalculationDetails);
}
}
公共类计算详细信息
{
公共int Id;
公共小数利率;
公共小数?金额;
公共ID;
公共字符串类别;
公共国际联合会;
}

无论如何,您应该避免这种方法,它使用反射,这在大多数情况下非常缓慢且可以避免。

如果
属性名称不一定是字符串,您可以使用lambda表达式来提取正确的字段。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);
    }
这类似于直接使用LINQ:

someCalculationDetailsCollection
    .Where(x => x.Id == 0 && x.Category == "category0")
    .Select(x => x.Rate)

到目前为止你试过什么?你能告诉我它是如何工作的吗,我是说propertyExtractor(匹配计算细节)?我无法将其与上面提到的LINQ查询联系起来。此外,我认为这不会处理空集合。
x=>x.Rate
是一种将CalculationDetails x作为参数并返回x.Rate的方法。因此,如果您说
Func myLambdaMethod=x=>x.Rate
,您可以执行
myLambdaMethod(新计算详细信息{Rate=22})
,结果将是22。它不会处理空/空集合是正确的。这与正确的匹配逻辑一起留给更了解特定案例需求的开发人员。
someCalculationDetailsCollection
    .Where(x => x.Id == 0 && x.Category == "category0")
    .Select(x => x.Rate)