C# 使用 Linq 替换集合项

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/749755/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 23:41:59  来源:igfitidea点击:

Replace a collection item using Linq

c#linqlinq-to-objects.net-3.0

提问by Vyas Bharghava

How do I find and replace a property using Linq in this specific scenario below:

在以下特定场景中,如何使用 Linq 查找和替换属性:

public interface IPropertyBag { }
public class PropertyBag : IPropertyBag
{
    public Property[] Properties { get; set; }

    public Property this[string name]
    {
        get { return Properties.Where((e) => e.Name == name).Single(); }
        //TODO: Just copying values... Find out how to find the index and replace the value 
        set { Properties.Where((e) => e.Name == name).Single().Value = value.Value; }
    }
}
public interface IPropertyBag { }
public class PropertyBag : IPropertyBag
{
    public Property[] Properties { get; set; }

    public Property this[string name]
    {
        get { return Properties.Where((e) => e.Name == name).Single(); }
        //TODO: Just copying values... Find out how to find the index and replace the value 
        set { Properties.Where((e) => e.Name == name).Single().Value = value.Value; }
    }
}

Thanks for helping out in advance.

感谢您提前提供帮助。

采纳答案by Daniel Brückner

Do not use LINQ because it will not improve the code because LINQ is designed to query collection and not to modify them. I suggest the following.

不要使用 LINQ,因为它不会改进代码,因为 LINQ 旨在查询集合而不是修改它们。我建议如下。

// Just realized that Array.IndexOf() is a static method unlike
// List.IndexOf() that is an instance method.
Int32 index = Array.IndexOf(this.Properties, name);

if (index != -1)
{
   this.Properties[index] = value;
}
else
{
   throw new ArgumentOutOfRangeException();
}

Why are Array.Sort() and Array.IndexOf() methods static?

为什么 Array.Sort() 和 Array.IndexOf() 方法是静态的?

Further I suggest not to use an array. Consider using IDictionary<String, Property>. This simplifies the code to the following.

此外,我建议不要使用数组。考虑使用IDictionary<String, Property>. 这将代码简化为以下内容。

this.Properties[name] = value;

Note that neither solution is thread safe.

请注意,这两种解决方案都不是线程安全的。



An ad hoc LINQ solution - you see, you should not use it because the whole array will be replaced with a new one.

一个特别的 LINQ 解决方案 - 你看,你不应该使用它,因为整个数组将被一个新的替换。

this.Properties = Enumerable.Union(
   this.Properties.Where(p => p.Name != name),
   Enumerable.Repeat(value, 1)).
   ToArray();

回答by Jonathan Rupp

[note: this answer was due to a misunderstanding of the question - see the comments on this answer. Apparently, I'm a little dense :(] Is your 'Property' a class or a struct?

[注意:这个答案是由于对问题的误解 - 请参阅对此答案的评论。显然,我有点密集:(] 你的“属性”是一个类还是一个结构?

This test passes for me:

这个测试对我来说通过了:

public class Property
{
    public string Name { get; set; }
    public string Value { get; set; }
}
public interface IPropertyBag { }
public class PropertyBag : IPropertyBag
{
    public Property[] Properties { get; set; }

    public Property this[string name]
    {
        get { return Properties.Where((e) => e.Name == name).Single(); }
        set { Properties.Where((e) => e.Name == name).Single().Value = value.Value; }
    }
}

[TestMethod]
public void TestMethod1()
{
    var pb = new PropertyBag() { Properties = new Property[] { new Property { Name = "X", Value = "Y" } } };
    Assert.AreEqual("Y", pb["X"].Value);
    pb["X"] = new Property { Name = "X", Value = "Z" };
    Assert.AreEqual("Z", pb["X"].Value);
}

I have to wonder why the getter returns a 'Property' instead of whatever datatype .Value, but I'm still curious why you're seeing a different result than what I am.

我想知道为什么 getter 返回一个“属性”而不是任何数据类型 .Value,但我仍然很好奇为什么你看到的结果与我不同。