c# tooltip show




Legen Sie die Objekteigenschaft mithilfe der Reflektion fest (7)

Basierend auf dem Vorschlag von MarcGravell habe ich die folgende statische Methode konstruiert: Die Methode ordnet generisch alle passenden Eigenschaften vom Quellobjekt zum Ziel mit FastMember zu

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

Gibt es einen Weg in C # 3.5, wo ich Reflektion verwenden kann, um eine Objekteigenschaft festzulegen?

Ex:

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

Ich möchte obj.Name mit Reflektion setzen. Etwas wie:

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

Gibt es eine Möglichkeit, dies zu tun?


Ich habe gerade ein Nuget-Paket veröffentlicht, das es ermöglicht, nicht nur die Eigenschaften der ersten Ebene, sondern auch verschachtelte Eigenschaften in dem gegebenen Objekt in beliebiger Tiefe einzurichten.

Hier ist das Paket

Legt den Wert einer Eigenschaft eines Objekts anhand seines Pfads vom Stamm fest.

Das Objekt kann ein komplexes Objekt sein, und die Eigenschaft kann eine verschachtelte Eigenschaft auf mehreren Ebenen sein oder eine Eigenschaft direkt unter dem Stamm. ObjectWriter findet die Eigenschaft mit dem Eigenschaftspfadparameter und aktualisiert seinen Wert. Eigenschaftenpfad sind die angehängten Namen der Eigenschaften, die vom Stamm bis zur Endknoteneigenschaft, die wir festlegen möchten, vom Trennzeichenfolgenparameter getrennt sind.

Verwendung:

Zum Einrichten der Eigenschaften direkt unter dem Objektstamm:

Ie. LineItem Klasse hat eine int-Eigenschaft namens ItemId

LineItem lineItem = new LineItem();

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

Zum Einrichten geschachtelter Eigenschaften mehrere Ebenen unterhalb des Objektstamms:

Ie. Invite Klasse hat eine Eigenschaft mit dem Namen State , die eine Eigenschaft namens Invite (Invite-Typ) hat, die eine Eigenschaft mit dem Namen Recipient , die über eine Eigenschaft namens Id .

Um die Dinge noch komplexer zu machen, ist die State Eigenschaft kein Referenztyp, sondern eine struct .

So können Sie die Id-Eigenschaft (auf den Zeichenfolgenwert "Outlook") am Ende des Objektbaums in einer einzelnen Zeile festlegen.

Invite invite = new Invite();

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

Ja, mit System.Reflection :

using System.Reflection;

...

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

Oder Sie können Marcs einen Liner in Ihre eigene Erweiterungsklasse einpacken:

public static class PropertyExtension{       

   public static void SetPropertyValue(this object obj, string propName, object value)
    {
        obj.GetType().GetProperty(propName).SetValue(obj, value, null);
    }
}

und nenne es so:

myObject.SetPropertyValue("myProperty", "myValue");

Als gutes Maß fügen wir eine Methode hinzu, um einen Eigenschaftswert zu erhalten:

public static object GetPropertyValue(this object obj, string propName)
{
        return obj.GetType().GetProperty(propName).GetValue (obj, null);
}

Sie können auch Folgendes tun:

Type type = target.GetType();

PropertyInfo prop = type.GetProperty("propertyName");

prop.SetValue (target, propertyValue, null);

where target ist das Objekt, für das die Eigenschaft festgelegt werden soll.


Sie können auch similar auf Felder zugreifen:

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

Mit Reflektion kann alles ein offenes Buch sein :) In meinem Beispiel sind wir an ein privates Instanzlevelfeld gebunden.


Verwenden Sie etwas wie folgt:

public static class PropertyExtension{       

   public static void SetPropertyValue(this object p_object, string p_propertyName, object value)
   {
    PropertyInfo property = p_object.GetType().GetProperty(p_propertyName);
    property.SetValue(p_object, Convert.ChangeType(value, property.PropertyType), null);
   }
}

oder

public static class PropertyExtension{       

   public static void SetPropertyValue(this object p_object, string p_propertyName, object value)
   {
    PropertyInfo property = p_object.GetType().GetProperty(p_propertyName);
    Type t = Nullable.GetUnderlyingType(property.PropertyType) ?? property.PropertyType;
    object safeValue = (value == null) ? null : Convert.ChangeType(value, t);

    property.SetValue(p_object, safeValue, null);
   }
}




properties