ist Es kann getan werden, aber das richtig tun wird ziemlich schwer sein (und es wird auf jeden Fall nicht in meiner Antwort passen). Die folgende einfache Implementierung wird davon ausgegangen, dass Ihr Objekt Eigenschaften nur Lese-Schreib-und parameterlose Konstruktor:
class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
Dieser leicht den Punkt besiegt, weil Sie wahrscheinlich diese verwenden, auf unveränderliche Typen wollen - aber dann immer Sie haben um den Konstruktor mit allen Argumenten aufzurufen, und es ist nicht klar, wie die Konstruktorparameter (wenn Sie eine Instanz erstellen) mit den Eigenschaften verknüpft werden, die Sie lesen können.
Die With
Methode erstellt eine neue Instanz, kopiert alle Werte Eigenschaft und setzt dann das eine, die Sie ändern möchten (die PropertyInfo
extrahiert aus dem Ausdrucksbaum mit - ohne Prüfung)
public static T With<T, P>(this T self, Expression<Func<T, P>> selector, P newValue)
{
var me = (MemberExpression)selector.Body;
var changedProp = (System.Reflection.PropertyInfo)me.Member;
var clone = Activator.CreateInstance<T>();
foreach (var prop in typeof(T).GetProperties())
prop.SetValue(clone, prop.GetValue(self));
changedProp.SetValue(clone, newValue);
return clone;
}
Folgende Demo verhält sich wie erwartet, aber wie gesagt, es hat viele Einschränkungen:
var person = new Person() { Name = "Tomas", Age = 1 };
var newPerson = person.With(p => p.Age, 20);
Im allgemeinen ich denke, eine universelle Reflexion basierende Methode verwendet wie With
hier vielleicht nicht su ch eine gute Idee, es sei denn, Sie haben viel Zeit, um es richtig zu implementieren. Es ist möglicherweise einfacher, für jeden verwendeten Typ eine Methode With
zu implementieren, die optionale Parameter verwendet und ihre Werte auf einen (manuell erstellten) geklonten Wert setzt, wenn der Wert nicht null
ist. Die Unterschrift wäre so etwas wie:
public Person With(string name=null, int? age=null) { ... }
Vielleicht wird dies nützlich sein: http://v2matveev.blogspot.com/2010/05/copy-and-update-in-c.html – desco
möglich duplicate von [C#: wie definiert man eine Erweiterungsmethode als "mit "in F #?] (http://stackoverflow.com/questions/6832880/c-how-to-define-an-extension-metho-as-with-in-f) –