384 Stimmen

Objekteigenschaft mit Reflexion festlegen

Gibt es eine Möglichkeit in C#, wo ich Reflexion verwenden können, um eine Objekteigenschaft festlegen?

Ex:

MyObject obj = new MyObject();
obj.Name = "Value";

Ich möchte die obj.Name mit Reflexion. So etwas wie:

Reflection.SetProperty(obj, "Name") = "Value";

Gibt es eine Möglichkeit, dies zu tun?

15voto

D Stanley Punkte 143923

Ja, mit System.Reflection :

using System.Reflection;

...

    string prop = "name";
    PropertyInfo pi = myObject.GetType().GetProperty(prop);
    pi.SetValue(myObject, "Bob", null);

13voto

JoshBerke Punkte 64214

Sie können auch auf ähnliche Weise auf Felder zugreifen:

var obj=new MyObject();
FieldInfo fi = obj.GetType().
  GetField("Name", BindingFlags.NonPublic | BindingFlags.Instance);
fi.SetValue(obj,value)

Mit Reflexion kann alles ein offenes Buch sein:) In meinem Beispiel binden wir an ein privates Feld auf Instanzebene.

10voto

user3679106 Punkte 99

Sie können dies ausprobieren, wenn Sie Eigenschaften eines Objekts aus einem anderen Objekt mit Hilfe von Eigenschaftsnamen massenhaft zuweisen wollen:

public static void Assign(this object destination, object source)
    {
        if (destination is IEnumerable && source is IEnumerable)
        {
            var dest_enumerator = (destination as IEnumerable).GetEnumerator();
            var src_enumerator = (source as IEnumerable).GetEnumerator();
            while (dest_enumerator.MoveNext() && src_enumerator.MoveNext())
                dest_enumerator.Current.Assign(src_enumerator.Current);
        }
        else
        {
            var destProperties = destination.GetType().GetProperties();
            foreach (var sourceProperty in source.GetType().GetProperties())
            {
                foreach (var destProperty in destProperties)
                {
                    if (destProperty.Name == sourceProperty.Name && destProperty.PropertyType.IsAssignableFrom(sourceProperty.PropertyType))
                    {
                        destProperty.SetValue(destination,     sourceProperty.GetValue(source, new object[] { }), new object[] { });
                        break;
            }
        }
    }
}

0voto

Dogu Arslan Punkte 3106

Ich habe gerade ein Nuget-Paket veröffentlicht, mit dem nicht nur die Eigenschaften der ersten Ebene, sondern auch verschachtelte Eigenschaften in einem bestimmten Objekt in beliebiger Tiefe eingerichtet werden können.

Hier ist das Paket

Legt den Wert einer Eigenschaft eines Objekts anhand seines Pfads von der Wurzel fest.

Das Objekt kann ein komplexes Objekt sein, und die Eigenschaft kann auf mehreren Ebenen tief verschachtelt sein, oder sie kann eine Eigenschaft direkt unter der Wurzel sein. ObjectWriter findet die Eigenschaft anhand des Parameters für den Eigenschaftspfad und aktualisiert ihren Wert. Der Eigenschaftspfad ist der angehängte Name der Eigenschaften, die von der Wurzel bis zur Eigenschaft des Endknotens, die wir einstellen wollen, besucht werden, begrenzt durch den Parameter "delimiter string".

Verwendung:

Zum Einstellen der Eigenschaften direkt unter dem Objekt Root:

D.h.. LineItem Klasse hat eine int-Eigenschaft namens ItemId

LineItem lineItem = new LineItem();

ObjectWriter.Set(lineItem, "ItemId", 13, delimiter: null);

Zum Einrichten verschachtelter Eigenschaften auf mehreren Ebenen unterhalb des Objekts Root:

D.h.. Invite Klasse hat eine Eigenschaft namens State die eine Eigenschaft namens Invite (vom Typ Invite), die eine Eigenschaft namens Recipient die eine Eigenschaft namens Id .

Um die Dinge noch komplizierter zu machen, ist die State Eigenschaft ist kein Referenztyp, sie ist eine struct .

Hier sehen Sie, wie Sie die Id-Eigenschaft (mit dem String-Wert "outlook") am unteren Ende des Objektbaums in einer einzigen Zeile festlegen können.

Invite invite = new Invite();

ObjectWriter.Set(invite, "State_Invite_Recipient_Id", "outlook", delimiter: "_");

0voto

Cogent Punkte 394

Auf der Grundlage des Vorschlags von MarcGravell habe ich die folgende statische Methode entwickelt allgemein weist alle übereinstimmenden Eigenschaften des Quellobjekts dem Ziel zu, indem es FastMember

 public static void DynamicPropertySet(object source, object target)
    {
        //SOURCE
        var src_accessor = TypeAccessor.Create(source.GetType());
        if (src_accessor == null)
        {
            throw new ApplicationException("Could not create accessor!");
        }
        var src_members = src_accessor.GetMembers();
        if (src_members == null)
        {
            throw new ApplicationException("Could not fetch members!");
        }
        var src_class_members = src_members.Where(x => x.Type.IsClass && !x.Type.IsPrimitive);
        var src_class_propNames = src_class_members.Select(x => x.Name);
        var src_propNames = src_members.Except(src_class_members).Select(x => x.Name);

        //TARGET
        var trg_accessor = TypeAccessor.Create(target.GetType());
        if (trg_accessor == null)
        {
            throw new ApplicationException("Could not create accessor!");
        }
        var trg_members = trg_accessor.GetMembers();
        if (trg_members == null)
        {
            throw new ApplicationException("Could not create accessor!");
        }
        var trg_class_members = trg_members.Where(x => x.Type.IsClass && !x.Type.IsPrimitive);
        var trg_class_propNames = trg_class_members.Select(x => x.Name);
        var trg_propNames = trg_members.Except(trg_class_members).Select(x => x.Name);

        var class_propNames = trg_class_propNames.Intersect(src_class_propNames);
        var propNames = trg_propNames.Intersect(src_propNames);

        foreach (var propName in propNames)
        {
            trg_accessor[target, propName] = src_accessor[source, propName];
        }
        foreach (var member in class_propNames)
        {
            var src = src_accessor[source, member];
            var trg = trg_accessor[target, member];
            if (src != null && trg != null)
            {
                DynamicPropertySet(src, trg);
            }
        }
    }

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X