Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.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-如何替换列表中的列表或属性值?_C#_Linq_List - Fatal编程技术网

C# C-如何替换列表中的列表或属性值?

C# C-如何替换列表中的列表或属性值?,c#,linq,list,C#,Linq,List,我已将控件与BindingList数据源绑定。比如说: var dataSource = new List<Model>() { new Model() { Name = "A", CostValue = 60 }, new Model() { Name = "B", CostValue = 0 } }; 那么,用新的CostValue替换dataSource bindinglist中的CostVa

我已将控件与BindingList数据源绑定。比如说:

var dataSource = new List<Model>()
{
   new Model()
   {
      Name = "A",
      CostValue = 60
   },
   new Model()
   {
      Name = "B",
      CostValue = 0
   }
};
那么,用新的CostValue替换dataSource bindinglist中的CostValue列表的最佳方法是什么呢?因为dataSource bindinglist中可能有很多模型,使用两个foreach循环会非常慢

我试图找出这两份清单之间的区别,但没有成功。似乎通过使用SELECT获取costValue,Except函数不起作用,这是为什么

 var list11 = dataSource.Select(x => x.CostValue).ToList();//If we create a new list with just values, the Except would work
 var newCostValue = new List<double>() {60,0};
 var dif = list11.Except(newCostValue).ToList();//Getting None, why is that?

提前谢谢

您需要保持相等,以便可以比较项目是否相等。

如果您也要获得名称,这可能会对您有所帮助

dataSource.First(d => d.Name == "B").CostValue = newCostValue[1];
但另一个可能是

dataSource.First(d => d.CostValue == newCostValue[0]).CostValue = newCostValue[1];

我想提供一个更好的答案,它在这里提供了更多的线程安全性。 由于项目可以删除,我假设,并且假设字段名唯一地映射到价格:

public class Model
{
    public string Name;
    public double CostValue;
}

public List<Model> dataSource = new List<Model>()
    {
        new Model()
        {
            Name = "A",
            CostValue = 60
        },
        new Model()
        {
            Name = "B",
            CostValue = 0
        }
    };

/// <summary>
/// Updates the original dataSource with the new prices
/// </summary>
/// <param name="newPrices">Dictionary whereas the Keys are names and values are CostValue of an item</param>
public void PriceChange(Dictionary<string, double> newPrices)
{
    foreach (Model model in dataSource)
    {
        if (newPrices.ContainsKey(model.Name))
            model.CostValue = newPrices[model.Name];
    }
}
因此,更新将花费一个运行时,而n是数据源中的项目数,当然,依赖项目名称本身而不是列表中的索引更安全

为什么?

因为如果您有另一个线程删除项目或修改项目,使其索引发生更改,您将遇到一个严重的问题,您将根据需要更新不同的项目


您需要更改的只是返回一个新的价格字典,而不是列表

模型的类型。CostValue?为什么不将新的值列表指定为数据源?@Damith如果模型包含更多字段或引用很重要,会发生什么情况,这是一种不好的做法i thinkHi@qub1n,谢谢您的建议。我曾试图实现IEquatable,但没有成功。CostValueComparer就是不打电话。但如果我创建两个虚拟列表,这个比较器将被执行。linq选择列表和泛型列表之间有什么区别?提供比较器是不够的,您的模型需要实现IEquatable接口并覆盖GetHashCode。您的模型实现了什么接口?公共类模型:IEquatable{public string Serie{get;set;}公共字符串RowName{get;set;}公共双成本值{get;set;}公共bool EqualsModel other{return other!=null&&Serie.Equalsother.Serie&&RowName.Equalsother.RowName;}}此比较器:公共类CostValueComparer:IEqualityComparer{public bool Equalsdouble x,double y y{return Math.Absx-y<1E-8;}公共int GetHashCodedouble obj{未选中{Debug.WriteLineCostValue HashCode:+obj.GetHashCode;返回obj.GetHashCode;}}}您好@Ori Refael,谢谢您的建议。由于新价格是由第三方dll提供的,因此要求他们更改其模式并不容易,但我会尝试一下,无论如何,谢谢。@Spencer我仍然建议您保留一个映射字典,它存储在请求之前,以便在返回响应时,您可以获取模型从包含index->Name的字典中选择的名称,然后使用该名称和值更新价格。
public class Model
{
    public string Name;
    public double CostValue;
}

public List<Model> dataSource = new List<Model>()
    {
        new Model()
        {
            Name = "A",
            CostValue = 60
        },
        new Model()
        {
            Name = "B",
            CostValue = 0
        }
    };

/// <summary>
/// Updates the original dataSource with the new prices
/// </summary>
/// <param name="newPrices">Dictionary whereas the Keys are names and values are CostValue of an item</param>
public void PriceChange(Dictionary<string, double> newPrices)
{
    foreach (Model model in dataSource)
    {
        if (newPrices.ContainsKey(model.Name))
            model.CostValue = newPrices[model.Name];
    }
}