15 Stimmen

Iteration der Liste in Reflection

Ich habe eine Eigenschaft namens Schüler, die vom Typ ist List<Student> .

In der Reflexion kann ich den Wert der Schülereigenschaft erhalten.

Das Problem ist nun, wie man die Liste der Schüler durchläuft.

Ich muss prüfen, ob StudentID [ irgendein Wert ] in dieser Sammlung enthalten ist.

var collection = studentPro.GetValue(studentObj,null);

//I need to iterate like this,

foreach(var item in collection)
{
     if(item.StudentID == 33)
         //Do stuff
}

Bitte helfen Sie mir.

19voto

Aliostad Punkte 78595

Sie müssen nur gießen es:

var collection = (List<Student>) studentPro.GetValue(studentObj,null);

Der Wert, der an Sie zurückgegeben und in var ist vom Typ object . Sie müssen es also nach List<Student> bevor Sie versuchen, sie in einer Schleife zu durchlaufen.

RANT

Deshalb habe ich persönlich nicht mögen var wird der Typ ausgeblendet - es sei denn, Sie bewegen in VS den Mauszeiger darauf. Wenn es mit Typ deklariert wurde object Es war sofort klar, dass wir sie nicht durchgehen können.


UPDATE

Ja, das ist gut. Aber Gießen sollte sein mit Reflexion geschehen. In Reflection kennen wir kennen wir den Typ der Liste nicht. Wir wissen nicht kennen den tatsächlichen Typ von studentObj

Um dies zu tun, können Sie sich an IEnumerable :

var collection = (IEnumerable) studentPro.GetValue(studentObj,null);

2voto

Stecya Punkte 22308

Versuchen Sie dies

IEnumerable<Student> collection = (IEnumerable<Student>)studentPro.GetValue(studentObj,null);

2voto

Robert Levy Punkte 28351

Andere haben vorgeschlagen, Casting auf List, aber ich werde davon ausgehen, dass dies nicht für Sie funktionieren wird ... wenn Sie Zugriff auf die Klasse Student hatte, würden Sie nicht mit Reflexion zu beginnen. Also stattdessen nur Cast zu IEnumerable und dann innerhalb Ihrer Schleife, müssen Sie Reflexion wieder verwenden, um zugreifen, was Eigenschaften, die Sie von jedem Element in der Sammlung möchten.

var collection = (IEnumerable)studentPro.GetValue(studentObj,null)

1voto

Daniel Hilgarth Punkte 165768

Der Weg, den Sie eingeschlagen haben, ist der richtige. Sie müssen nur Ihren Code korrigieren und den Rückgabewert von GetValue :

var collection = (List<Student>)studentPro.GetValue(studentObj,null);

foreach(var item in collection)
{
     if(item.StudentID == 33)
         //Do stuff
}

0voto

Shahab Khan Punkte 1

Sie können ein POCO-Objekt aus Ihrem Proxy-Objekt wie unten beschrieben erstellen. Bitte beachten Sie, dass ich mich auf die Verwendung des XMLIgnore-Attributs verlasse, um zirkuläre Referenzen zu unterbrechen

static object DeepCopy(object obj, Type targetType)
    {
        if (obj != null)
        {
            Type t = obj.GetType();

            object objCopy = Activator.CreateInstance(targetType);

            Type copyType = targetType;

            var props =
                t.GetProperties();

                    //.Where(x => x.PropertyType.GetCustomAttributes(typeof(XmlIgnoreAttribute), false).Length == 0);
            foreach (var propertyInfo in props)
            {
                var targetProperty = copyType.GetProperties().Where(x => x.Name == propertyInfo.Name).First();

                if (targetProperty.GetCustomAttributes(typeof(XmlIgnoreAttribute), false).Length > 0)
                {
                    continue;
                }

                if (propertyInfo.PropertyType.IsClass)
                {
                    if (propertyInfo.PropertyType.GetInterface("IList", true)!=null)
                    {
                        var list = (IList)Activator.CreateInstance(targetProperty.PropertyType);

                        targetProperty.SetValue(objCopy,list);

                        var sourceList = propertyInfo.GetValue(obj) as IList;

                        foreach (var o in sourceList)
                        {
                            list.Add(DeepCopy(o, targetProperty.PropertyType.UnderlyingSystemType.GenericTypeArguments[0]));
                        }

                    }
                    else if (propertyInfo.PropertyType == typeof(string))
                    {
                        targetProperty.SetValue(objCopy, propertyInfo.GetValue(obj));
                    }
                    else
                    {
                        targetProperty.SetValue(objCopy, DeepCopy(propertyInfo.GetValue(obj), targetProperty.PropertyType));
                    }

                }
                else
                {
                    targetProperty.SetValue(objCopy,propertyInfo.GetValue(obj));
                }
            }

            return objCopy;

        }
        return null;
    }

    class MyDbContext:DbContext
{
    public MyDbContext():base(@"Server=(LocalDb)\v12.0;Trusted_Connection=True;")
    {

    }

    public DbSet<Table1> Table1s { get; set; }

    public DbSet<Table2> Table2s { get; set; }

}

public class Table1
{
    public int ID { get; set; }

    public string name { get; set; }

    virtual public List<Table2> Table2s { get; set; }
}

public class Table2
{
    public int ID { get; set; }

    public string Name { get; set; }
    [XmlIgnore]
    virtual public Table1 Table1 { get; set; }
}

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