1210 Stimmen

Abrufen des Eigenschaftswerts aus einer Zeichenkette mittels Reflexion

Ich versuche die Implementierung der Datentransformation mit Reflection 1 Beispiel in meinem Code.

Le site GetSourceValue Funktion hat einen Schalter, der verschiedene Typen vergleicht, aber ich möchte diese Typen und Eigenschaften entfernen und die GetSourceValue den Wert der Eigenschaft mit nur einer einzigen Zeichenkette als Parameter abrufen. Ich möchte eine Klasse und eine Eigenschaft in der Zeichenfolge übergeben und den Wert der Eigenschaft auflösen.

Ist dies möglich?

1 <a href="https://web.archive.org/web/20130815002453/http://msmvps.com/blogs/shahed/archive/2008/07/24/c-reflection-tips-data-transformation-using-reflection.aspx" rel="noreferrer">Webarchiv-Version des ursprünglichen Blogbeitrags</a>

5voto

A Ghazal Punkte 2455

Mit PropertyInfo des System.Reflexion Namensraum. Reflection kompiliert einwandfrei, egal auf welche Eigenschaft wir zuzugreifen versuchen. Der Fehler tritt während der Laufzeit auf.

    public static object GetObjProperty(object obj, string property)
    {
        Type t = obj.GetType();
        PropertyInfo p = t.GetProperty("Location");
        Point location = (Point)p.GetValue(obj, null);
        return location;
    }

Es funktioniert gut, um die Location-Eigenschaft eines Objekts zu erhalten

Label1.Text = GetObjProperty(button1, "Location").ToString();

Wir erhalten den Standort: {X=71,Y=27} Auf die gleiche Weise können wir auch Standort.X oder Standort.Y zurückgeben.

4voto

Komal Narang Punkte 41
public class YourClass
{
    //Add below line in your class
    public object this[string propertyName] => GetType().GetProperty(propertyName)?.GetValue(this, null);
    public string SampleProperty { get; set; }
}

//And you can get value of any property like this.
var value = YourClass["SampleProperty"];

3voto

gridtrak Punkte 653

Der folgende Code ist eine rekursive Methode zur Anzeige der gesamten Hierarchie aller Eigenschaftsnamen und -werte, die in der Instanz eines Objekts enthalten sind. Diese Methode verwendet eine vereinfachte Version von AlexDs GetPropertyValue() Antwort oben in diesem Thema. Dank dieses Diskussionsthreads konnte ich herausfinden, wie man das macht!

Ich verwende diese Methode zum Beispiel, um eine Explosion oder einen Dump aller Eigenschaften in einer WebService Antwort, indem Sie die Methode wie folgt aufrufen:

PropertyValues_byRecursion("Response", response, false);

public static object GetPropertyValue(object srcObj, string propertyName)
{
  if (srcObj == null) 
  {
    return null; 
  }
  PropertyInfo pi = srcObj.GetType().GetProperty(propertyName.Replace("[]", ""));
  if (pi == null)
  {
    return null;
  }
  return pi.GetValue(srcObj);
}

public static void PropertyValues_byRecursion(string parentPath, object parentObj, bool showNullValues)
{
  /// Processes all of the objects contained in the parent object.
  ///   If an object has a Property Value, then the value is written to the Console
  ///   Else if the object is a container, then this method is called recursively
  ///       using the current path and current object as parameters

  // Note:  If you do not want to see null values, set showNullValues = false

  foreach (PropertyInfo pi in parentObj.GetType().GetTypeInfo().GetProperties())
  {
    // Build the current object property's namespace path.  
    // Recursion extends this to be the property's full namespace path.
    string currentPath = parentPath + "." + pi.Name;

    // Get the selected property's value as an object
    object myPropertyValue = GetPropertyValue(parentObj, pi.Name);
    if (myPropertyValue == null)
    {
      // Instance of Property does not exist
      if (showNullValues)
      {
        Console.WriteLine(currentPath + " = null");
        // Note: If you are replacing these Console.Write... methods callback methods,
        //       consider passing DBNull.Value instead of null in any method object parameters.
      }
    }
    else if (myPropertyValue.GetType().IsArray)
    {
      // myPropertyValue is an object instance of an Array of business objects.
      // Initialize an array index variable so we can show NamespacePath[idx] in the results.
      int idx = 0;
      foreach (object business in (Array)myPropertyValue)
      {
        if (business == null)
        {
          // Instance of Property does not exist
          // Not sure if this is possible in this context.
          if (showNullValues)
          {
            Console.WriteLine(currentPath  + "[" + idx.ToString() + "]" + " = null");
          }
        }
        else if (business.GetType().IsArray)
        {
          // myPropertyValue[idx] is another Array!
          // Let recursion process it.
          PropertyValues_byRecursion(currentPath + "[" + idx.ToString() + "]", business, showNullValues);
        }
        else if (business.GetType().IsSealed)
        {
          // Display the Full Property Path and its Value
          Console.WriteLine(currentPath + "[" + idx.ToString() + "] = " + business.ToString());
        }
        else
        {
          // Unsealed Type Properties can contain child objects.
          // Recurse into my property value object to process its properties and child objects.
          PropertyValues_byRecursion(currentPath + "[" + idx.ToString() + "]", business, showNullValues);
        }
        idx++;
      }
    }
    else if (myPropertyValue.GetType().IsSealed)
    {
      // myPropertyValue is a simple value
      Console.WriteLine(currentPath + " = " + myPropertyValue.ToString());
    }
    else
    {
      // Unsealed Type Properties can contain child objects.
      // Recurse into my property value object to process its properties and child objects.
      PropertyValues_byRecursion(currentPath, myPropertyValue, showNullValues);
    }
  }
}

3voto

Rahma Samaroon Punkte 632
public static TValue GetFieldValue<TValue>(this object instance, string name)
{
    var type = instance.GetType(); 
    var field = type.GetFields(BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance).FirstOrDefault(e => typeof(TValue).IsAssignableFrom(e.FieldType) && e.Name == name);
    return (TValue)field?.GetValue(instance);
}

public static TValue GetPropertyValue<TValue>(this object instance, string name)
{
    var type = instance.GetType();
    var field = type.GetProperties(BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance).FirstOrDefault(e => typeof(TValue).IsAssignableFrom(e.PropertyType) && e.Name == name);
    return (TValue)field?.GetValue(instance);
}

2voto

Recursor Punkte 522

Hier ist eine weitere Möglichkeit, eine verschachtelte Eigenschaft zu finden, bei der die Zeichenfolge nicht den Verschachtelungspfad angeben muss. Dank an Ed S. für die Methode der einzelnen Eigenschaft.

    public static T FindNestedPropertyValue<T, N>(N model, string propName) {
        T retVal = default(T);
        bool found = false;

        PropertyInfo[] properties = typeof(N).GetProperties();

        foreach (PropertyInfo property in properties) {
            var currentProperty = property.GetValue(model, null);

            if (!found) {
                try {
                    retVal = GetPropValue<T>(currentProperty, propName);
                    found = true;
                } catch { }
            }
        }

        if (!found) {
            throw new Exception("Unable to find property: " + propName);
        }

        return retVal;
    }

        public static T GetPropValue<T>(object srcObject, string propName) {
        return (T)srcObject.GetType().GetProperty(propName).GetValue(srcObject, null);
    }

0 Stimmen

Es wäre vielleicht besser zu prüfen, ob Type.GetProperty 収益 null statt des Aufrufs GetValue und mit NullReferenceException in eine Schleife geworfen wird.

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