Frage

Gibt es eine Möglichkeit (durch foreach vorzugsweise) iterieren einer Sammlung mit Reflexion? Ich Iterieren über die Eigenschaften in einem Objekt Reflexion verwendet wird, und wenn das Programm auf eine Art bekommt, die eine Sammlung ist, würde Ich mag es, den Inhalt der Sammlung iterieren und in der Lage, die Objekte in der Sammlung zuzugreifen.

Im Moment habe ich ein Attribut auf all meine Eigenschaften festgelegt, mit einem IsCollection Flag auf true auf den Eigenschaften festgelegt, die Sammlungen sind. Mein Code prüft für diese Flagge und wenn es wahr ist, wird es die Art Reflexion verwendet wird. Gibt es eine Möglichkeit GetEnumerator oder Gegenstände irgendwie auf einer Sammlung aufrufen zu können, über die Elemente iterieren?

War es hilfreich?

Lösung

hatte ich dieses Problem, sondern Reflexion zu verwenden, landete ich Überprüfung nur, wenn es IEnumerable war. Alle Kollektionen dass implementieren.

if (item is IEnumerable)
{
    foreach (object o in (item as IEnumerable))
    {

    }
} else {
   // reflect over item
}

Andere Tipps

Ich habe versucht, eine ähnliche Technik zu verwenden, wie Darren vorgeschlagen, passen jedoch nur, dass nicht nur Sammlungen IEnumerable implementieren. string zum Beispiel ist auch IEnumerable und wird über die Charaktere durchlaufen.

Hier ist eine kleine Funktion Ich verwende, um zu bestimmen, ob ein Objekt eine Sammlung (die auch zählbare sein wird, da ICollection auch IEnumerable ist).

    public bool isCollection(object o)
    {
        return typeof(ICollection).IsAssignableFrom(o.GetType())
            || typeof(ICollection<>).IsAssignableFrom(o.GetType());
    }

Sie einfach den Wert der Immobilie erhalten und wirft sie dann in eine IEnumerable. Hier finden Sie einige (ungetestet) Code, den Sie eine Idee zu geben:

ClassWithListProperty obj = new ClassWithListProperty();
obj.List.Add(1);
obj.List.Add(2);
obj.List.Add(3);

Type type = obj.GetType();
PropertyInfo listProperty = type.GetProperty("List", BindingFlags.Public);
IEnumerable listObject = (IEnumerable) listProperty.GetValue(obj, null);

foreach (int i in listObject)
    Console.Write(i); // should print out 123

Die besten könnte man wahrscheinlich, wenn das Objekt implementiert Schnittstellen bestimmte Sammlung Sie wäre zu überprüfen - wahrscheinlich IEnumerable würde alles sein, was Sie brauchen. Dann ist es nur eine Frage des Aufrufs GetEnumerator () von der Aufgabe, und mit IEnumerator.MoveNext () und IEnumerator.Current dich durch die Sammlung zu arbeiten.

Dies wird nicht helfen, wenn die Sammlung nicht diese Schnittstellen implementieren, aber wenn das der Fall ist es nicht wirklich viel von einer Sammlung ist, nehme ich an.

Nur zur Information kann es von jemandem Hilfe sein wird ... Ich hatte eine Klasse mit verschachtelten Klassen und Sammlung von einigen anderen Klassen. Ich wollte die Eigenschaftswerte der Klasse als auch verschachtelter Klassen und Sammlung von Klassen speichern. Mein Code ist wie folgt:

 public void LogObject(object obj, int indent)
    {
        if (obj == null) return;
        string indentString = new string(' ', indent);
        Type objType = obj.GetType();
        PropertyInfo[] properties = objType.GetProperties();

        foreach (PropertyInfo property in properties)
        {
            Type tColl = typeof(ICollection<>);
            Type t = property.PropertyType;
            string name = property.Name;


            object propValue = property.GetValue(obj, null); 
            //check for nested classes as properties
            if (property.PropertyType.Assembly == objType.Assembly)
            {
                string _result = string.Format("{0}{1}:", indentString, property.Name);
                log.Info(_result);
                LogObject(propValue, indent + 2);
            }
            else
            {
                string _result = string.Format("{0}{1}: {2}", indentString, property.Name, propValue);
                log.Info(_result);
            }

            //check for collection
            if (t.IsGenericType && tColl.IsAssignableFrom(t.GetGenericTypeDefinition()) ||
                t.GetInterfaces().Any(x => x.IsGenericType && x.GetGenericTypeDefinition() == tColl))
            {
                //var get = property.GetGetMethod();
                IEnumerable listObject = (IEnumerable)property.GetValue(obj, null);
                if (listObject != null)
                {
                    foreach (object o in listObject)
                    {
                        LogObject(o, indent + 2);
                    }
                }
            }
        }
    }

Ein nannte diese Funktion

LogObject(obj, 0);

Allerdings habe ich einige structs in meinen Klassen und ich brauche, um herauszufinden, wie sie ihre Werte erhalten. Moreoevr, ich habe einige LIst. Ich brauche ihren Wert sowie zu bekommen .... Ich werde schreiben, wenn ich meinen Code aktualisieren.

Wenn Ihr mit Reflexion Sie müssen nicht unbedingt eine Instanz dieses Objekts. Sie müßten eine Instanz dieser Art von der Lage zu schaffen, durch die Eigenschaften des Objekts iterieren. Also, wenn Sie mithilfe von Reflektion die ConstructorInfo.Invoke () verwenden (?) Methode eine neue Instanz oder Punkt auf eine Instanz des Typs zu schaffen.

Ich würde die Type.FindInterfaces Methode betrachten. Dies kann die Schnittstellen von einem bestimmten Typ implementiert herauszufiltern. Wie in PropertyInfo.PropertyType.FindInterfaces (filterMethod, FILTER). Sie können IEnumerable filtern und sehen, ob alle Ergebnisse zurückgegeben werden. MSDN hat ein großartiges Beispiel in der Methode Dokumentation.

Wenn Sie nicht eine Instanz des Objekts, sondern eine Art verwenden, können Sie die folgenden Befehle verwenden:

// type is IEnumerable
if (type.GetInterface("IEnumerable") != null)
{
}

Ein ziemlich einfacher Ansatz wäre, um das Objekt als Sammlung Typ gegossen und direkt verwendet diese.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top