it-swarm.com.de

Ruft Eigenschaften und Werte von unbekannten Objekten ab

Aus der Welt von PHP Ich habe beschlossen, C # auszuprobieren. Ich habe eine Suche durchgeführt, kann aber anscheinend keine Antwort darauf finden, wie ich das Äquivalent dazu machen soll.

$object = new Object();

$vars = get_class_vars(get_class($object));

foreach($vars as $var)
{
    doSomething($object->$var);
}

Ich habe im Grunde eine Liste eines Objekts. Das Objekt kann einer von drei verschiedenen Typen sein und verfügt über eine Reihe von öffentlichen Eigenschaften. Ich möchte in der Lage sein, eine Liste der Eigenschaften für das Objekt zu erhalten, sie zu durchlaufen und sie dann in eine Datei zu schreiben. Ich denke, das hat etwas mit C # -Reflexion zu tun, aber es ist alles neu für mich.

Jede Hilfe wäre sehr dankbar.

135
m4rc

Das sollte es tun:

Type myType = myObject.GetType();
IList<PropertyInfo> props = new List<PropertyInfo>(myType.GetProperties());

foreach (PropertyInfo prop in props)
{
    object propValue = prop.GetValue(myObject, null);

    // Do something with propValue
}
251
Cocowalla

Ja, Reflexion wäre der richtige Weg. Zuerst würden Sie das Type erhalten, das den Typ (zur Laufzeit) der Instanz in der Liste darstellt. Sie können dies tun, indem Sie die GetType -Methode für Object aufrufen. Da es sich um die Klasse Object handelt, kann es von jedem Objekt in .NET aufgerufen werden, da alle Typen von Object ( naja, technisch nicht alles , aber das ist hier nicht wichtig).

Sobald Sie die Instanz Type haben, können Sie die Methode GetProperties aufrufen, um die Instanzen PropertyInfo abzurufen, die die Laufzeitinformationen zu den Eigenschaften auf der Type.

Beachten Sie, dass Sie die Überladungen von GetProperties verwenden können, um zu klassifizieren , welche Eigenschaften Sie abrufen.

Von dort aus schreiben Sie die Informationen einfach in eine Datei.

Ihr Code über, übersetzt, wäre:

// The instance, it can be of any type.
object o = <some object>;

// Get the type.
Type type = o.GetType();

// Get all public instance properties.
// Use the override if you want to classify
// which properties to return.
foreach (PropertyInfo info in type.GetProperties())
{
    // Do something with the property info.
    DoSomething(info);
}

Beachten Sie, dass Sie, wenn Sie Methoden- oder Feldinformationen benötigen, die Überladung von GetMethods oder GetFields aufrufen müssen Methoden jeweils.

Beachten Sie auch, dass es eine Sache ist, die Elemente einer Datei aufzulisten, aber Sie sollten diese Informationen nicht verwenden , um die Logik basierend auf Eigenschaftssätzen zu steuern.

Angenommen, Sie haben die Kontrolle über die Implementierungen der Typen, sollten Sie von einer gemeinsamen Basisklasse ableiten oder eine gemeinsame Schnittstelle implementieren und die Aufrufe auf diesen ausführen (Sie können die Zeichen as oder - verwenden. is Operator, um zu bestimmen, mit welcher Basisklasse/Schnittstelle Sie zur Laufzeit arbeiten).

Wenn Sie diese Typdefinitionen jedoch nicht steuern und die Logik basierend auf dem Mustervergleich steuern müssen, ist dies in Ordnung.

17
casperOne
void Test(){
    var obj = new{a="aaa", b="bbb"};

    var val_a = obj.GetValObjDy("a"); //="aaa"
    var val_b = obj.GetValObjDy("b"); //="bbb"
}
//create in a static class
static public object GetValObjDy(this object obj, string propertyName)
{            
     return obj.GetType().GetProperty(propertyName).GetValue(obj, null);
}
16
Vo Van Khoa

nun, in C # ist es ähnlich. Hier ist eines der einfachsten Beispiele (nur für öffentliche Objekte):

var someObject = new { .../*properties*/... };
var propertyInfos = someObject.GetType().GetProperties();
foreach (PropertyInfo pInfo in PropertyInfos)
{
    string propertyName = pInfo.Name; //gets the name of the property
    doSomething(pInfo.GetValue(someObject,null));
}
10
AlexanderMP

Um einen bestimmten Eigenschaftswert aus dem Eigenschaftsnamen zu erhalten

public class Bike{
public string Name {get;set;}
}

Bike b = new Bike {Name = "MyBike"};

um auf den Eigenschaftswert von Name über den Zeichenfolgennamen der Eigenschaft zuzugreifen

public object GetPropertyValue(string propertyName)
{
//returns value of property Name
return this.GetType().GetProperty(propertyName).GetValue(this, null);
} 
9
RAJ

Sie können GetType - GetProperties - Linq Foreach verwenden:

obj.GetType().GetProperties().ToList().ForEach(p =>{
                                                        //p is each PropertyInfo
                                                        DoSomething(p);
                                                    });
3
Antonio DB

Hier ist etwas, mit dem ich ein IEnumerable<T> in eine DataTable, die Spalten enthält, die die Eigenschaften von T darstellen, mit einer Zeile für jedes Element in der IEnumerable:

public static DataTable ToDataTable<T>(IEnumerable<T> items)
{
    var table = CreateDataTableForPropertiesOfType<T>();
    PropertyInfo[] piT = typeof(T).GetProperties();
    foreach (var item in items)
    {
        var dr = table.NewRow();
        for (int property = 0; property < table.Columns.Count; property++)
        {
            if (piT[property].CanRead)
            {
                var value = piT[property].GetValue(item, null);
                if (piT[property].PropertyType.IsGenericType)
                {
                    if (value == null)
                    {
                        dr[property] = DBNull.Value;
                    }
                    else
                    {
                        dr[property] = piT[property].GetValue(item, null);
                    }
                }
                else
                {
                    dr[property] = piT[property].GetValue(item, null);
                }
            }
        }
        table.Rows.Add(dr);
    }
    return table;
}

public static DataTable CreateDataTableForPropertiesOfType<T>()
{
    DataTable dt = new DataTable();
    PropertyInfo[] piT = typeof(T).GetProperties();
    foreach (PropertyInfo pi in piT)
    {
        Type propertyType = null;
        if (pi.PropertyType.IsGenericType)
        {
            propertyType = pi.PropertyType.GetGenericArguments()[0];
        }
        else
        {
            propertyType = pi.PropertyType;
        }
        DataColumn dc = new DataColumn(pi.Name, propertyType);

        if (pi.CanRead)
        {
            dt.Columns.Add(dc);
        }
    }
    return dt;
}

Das ist "etwas" überkompliziert, aber eigentlich ist es ziemlich gut zu sehen, was das Ergebnis ist, da man es mit einem List<T> von zum Beispiel:

public class Car
{
    string Make { get; set; }
    int YearOfManufacture {get; set; }
}

Und Sie erhalten eine DataTable mit der folgenden Struktur zurück:

Make (String)
Herstellungsjahr (int)

Mit einer Zeile pro Artikel in Ihrem List<Car>

2
Rob

In diesem Beispiel werden alle Zeichenfolgeneigenschaften eines Objekts gekürzt.

public static void TrimModelProperties(Type type, object obj)
{
    var propertyInfoArray = type.GetProperties(
                                    BindingFlags.Public | 
                                    BindingFlags.Instance);
    foreach (var propertyInfo in propertyInfoArray)
    {
        var propValue = propertyInfo.GetValue(obj, null);
        if (propValue == null) 
            continue;
        if (propValue.GetType().Name == "String")
            propertyInfo.SetValue(
                             obj, 
                             ((string)propValue).Trim(), 
                             null);
    }
}
1
Brian Paske

Ich habe nicht gefunden, dass dies funktioniert, sagen wir Anwendungsobjekte. Ich habe jedoch Erfolg gehabt mit

var serializer = new System.Web.Script.Serialization.JavaScriptSerializer();

string rval = serializer.Serialize(myAppObj);
0
jcsubmit