2010-09-19 15 views
12

Ich schreibe einen Validierungscode. Der Code wird Daten an einen Web-Service übergeben und entscheiden, ob er die Aktion ausführen kann, oder eine Nachricht an den Anrufer, dass sie einige Felder verpasst haben.Wie gehe ich mit Arrays mit Reflektion um

Ich habe es am meisten funktioniert außer für Arrays. Ich markiere die Eigenschaften mit einem [RequiredField] -Attribut, um benötigte Felder darzustellen. Wenn das also einige meiner Daten sind,

Also was habe ich zu arbeiten? Ich habe Validierungen von Daten und Strings funktioniert. Es verwendet Rekursion, um eine beliebige Tiefe zu erreichen, die für die Daten erforderlich ist.

Aber ... so was ist mit den beiden Arrays dort. Der erste ist eine Reihe von Enums. Ich möchte in diesem Fall überprüfen, dass das Array nicht leer ist.

Die zweite ist das Array von DummyWebserviceData2-Werten. Ich muss jeden Wert herausziehen und einzeln betrachten.

den Code ich so sieht es aus, scheint

foreach (PropertyInfo propertyInfo in data.GetType().GetProperties()) 
{ 
    if (propertyInfo.PropertyType.IsArray) 
    { 
     // this craps out 

     object[] array = (object[])propertyInfo.GetValue(data, new object[] { 0 }); 

    } 
} 

So etwas geschrieben haben, zu vereinfachen es mir, dass die erste Sache ist, dass ich sagen kann, es ist ein Array. Aber wie kann ich dann sagen, wie viele Gegenstände im Array sind?

Antwort

19

Zur Laufzeit wird das Objekt dynamisch aus dem Array Datentyp (this MSDN topic details that) subclassed worden sind, deshalb brauchen Sie nicht in das Array zu reflektieren, können Sie die object-Array werfen können, und verwenden Sie dann den Array.GetValue Instanzmethode:

Array a = (Array)propertyInfo.GetValue(data); 
for(int i = 0; i< a.Length; i++) 
{ 
    object o = a.GetValue(i); 
} 

Sie können auch als auch ein Array iterieren - da von .Net 2.0 ab:

In der .NET Framework-Version 2.0 implementiert die Array-Klasse die generischen Schnittstellen System.Collections.Generic :: IList, System.Collections.Generic :: ICollection und System.Collections.Generic :: IEnumerable.

Sie müssen die T nicht kennen, denn von diesen können Sie ein IEnumerable erhalten; Sie können dann eine Cast() -Operation verwenden oder in der Tat nur auf der Ebene object arbeiten.

übrigens der Grund, warum Ihr Code funktioniert nicht, weil Sie nicht ein Array von MyType[]-object[] werfen kann, weil object[] kein Basistyp MyType[] ist - nur object ist.

+0

beachten Sie nur, dass Sie nicht die IList oder ICollection Interface-Implementierung verwenden können, um die Array-Inhalt zu ändern - wie die oben erwähnten MDSN Thema Staaten - sie alle werfen 'NotSupportedException' –

+1

Richtig. Ich recherchierte und stieß auf vieles, was Sie oben erwähnt haben. Was ich auch gemacht habe ist, dass der Array-Rang tatsächlich 1 ist. Ansonsten könnte das Array Array [] [] sein. Danke für Ihre Hilfe. Sehr geschätzt. – peter

+2

+1 für den 'Cast()' Vorschlag. . 'MyType [] a = ((Array) propertyInfo.GetValue (Daten)) Guss () .ToArray();' –

4
foreach (PropertyInfo propertyInfo in data.GetType().GetProperties()) 
{ 
    if (propertyInfo.PropertyType.IsArray) 
    { 
     // first get the array 
     object[] array = (object[])propertyInfo.GetValue(data) 

     // then find the length 
     int arrayLength = array.GetLength(0); 

     // now check if the length is > 0 

    } 
} 
+0

schließen - aber das wird nicht funktionieren, weil 'data' nicht das Array ist, ist es das' mit einer Eigenschaft object', die das Array - die 'propertyInfo' verwendet werden muss, um das Array zuerst –

+0

bearbeitet zugreifen um das zu korrigieren ... – Clicktricity

0

Die Antwort mit dem Array ist nett, aber wie erwähnt, funktioniert es nicht für einige andere Sammlungsarten. Wenn Sie nicht wissen, was Ihre Sammlung Art der Versuch etwas wie:

IEnumerable<object> a = (IEnumerable<object>)myPropInfo.GetValue(myResourceObject); 
// at least foreach now is available 
foreach (object o in a) 
{ 
    // get the value 
    string valueAsString = o.ToString(); 
} 
1

Diese Methode funktioniert recht gut, und es ist einfacher Code.

var array = ((IEnumerable)propertyInfo.GetValue(instance)).Cast<object>().ToArray(); 
Verwandte Themen