Domanda

Come faccio a trovare e sostituire una proprietà utilizzando LINQ in questo specifico scenario di seguito:

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

Grazie per l'aiuto in anticipo.

È stato utile?

Soluzione

Non utilizzare LINQ perché non migliorerà il codice perché LINQ è stato progettato per eseguire query di raccolta e non di modificarli. Suggerisco quanto segue.

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

Perché Array.Sort () e Array.indexOf () metodi statici?

Inoltre suggerisco di non usare un array. Considerare l'utilizzo di IDictionary<String, Property>. Questo semplifica il codice di seguito.

this.Properties[name] = value;

Si noti che nessuna delle due soluzioni è thread-safe.


Una soluzione ad hoc, LINQ - che si vede, non si deve usare perché l'intero array verrà sostituito con uno nuovo

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

Altri suggerimenti

[Nota: La risposta è stata causa di un malinteso della questione - si vedano i commenti su questa risposta. A quanto pare, sono un po 'denso :(] È il vostro 'proprietà' di una classe o di una struttura?

Questo test passa per 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);
}

Mi chiedo il motivo per cui il getter restituisce un 'Proprietà' al posto di qualsiasi tipo di dati .Value, ma io sono ancora curioso di sapere perchè si sta vedendo un risultato diverso da quello che sono.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top