استبدال عنصر مجموعة باستخدام 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.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);
}
يجب أن أتساءل لماذا إرجاع Getter "خاصية" بدلا من أي نوع من Datatype .value، لكنني ما زلت فضولي لماذا ترى نتيجة مختلفة عن ما أنا عليه.