使用Linq替换集合项

时间:2009-04-14 23:42:04

标签: c# linq linq-to-objects .net-3.0

如何在以下特定情况下使用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; } } } 感谢您提前帮忙。

2 个答案:

答案 0 :(得分:6)

不要使用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?

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

this.Properties[name] = value;

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


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

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

答案 1 :(得分:0)

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

此测试通过我:

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);
}

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