Замените элемент коллекции с помощью Linq
-
09-09-2019 - |
Вопрос
Как мне найти и заменить свойство с помощью 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; }
}
}
Спасибо за помощь заранее.
Решение
Не используйте 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();
}
Почему методы Array.Sort() и Array.IndexOf() являются статическими?
Далее предлагаю не использовать массив.Рассмотрите возможность использования IDictionary<String, Property>
.Это упрощает код до следующего.
this.Properties[name] = value;
Обратите внимание, что ни одно из решений не является потокобезопасным.
Специальное решение LINQ — понимаете, не стоит его использовать, потому что весь массив будет заменен на новый.
this.Properties = Enumerable.Union(
this.Properties.Where(p => p.Name != name),
Enumerable.Repeat(value, 1)).
ToArray();
Другие советы
[примечание:этот ответ произошел из-за неправильного понимания вопроса - см. комментарии к этому ответу.Видимо, я немного плотный :(] Ваше «собственность» класс или структура?
Этот тест проходит для меня:
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);
}
Мне приходится задаться вопросом, почему метод получения возвращает «Свойство» вместо какого-либо типа данных. Значение, но мне все еще любопытно, почему вы видите результат, отличный от того, что я.