2009-08-03 5 views
3

J'essaie d'obtenir les informations de champ d'une valeur de tableau à partir d'une structure. Jusqu'à présent, j'ai ce qui suit, mais je ne vois pas comment obtenir l'infomration que je veux.Comment obtenir le FieldInfo d'un champ de tableau?

[StructLayout(LayoutKind.Sequential)] 
    public struct Test 
    { 
     public byte Byte1; 
     [MarshalAs(UnmanagedType.ByValArray, SizeConst=3)] 
     public Test2[] Test1; 
    } 

    BindingFlags struct_field_flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly; 
    FieldInfo[] all_struct_fields = typeof(Test).GetFields(struct_field_flags); 
    foreach (FieldInfo struct_field in all_struct_fields) 
    { 
     if(struct_field.FieldType.IsArray) 
     { 
      // Get FieldInfo for each value in the Test1 array within Test structure 
     } 
    } 

Donc, si je l'ai fait:

Type array_type = struct_field.FieldType.GetElementType(); 

Ce retournerait Test2 le type, mais je ne veux pas que le type du tableau, je veux que le FieldInfo ou les champs de cette structure afin que je puisse définir des valeurs de à l'intérieur.

Répondre

3

Désolé pour la mauvaise réponse initiale . J'étais trop paresseux pour créer mon propre type Test2 donc j'ai utilisé une chaîne à la place. Voici la bonne réponse (je l'espère):

Je l'ai fait ce que vous voulez faire avec le code suivant:

class Program 
{ 
    static void Main(string[] args) 
    { 
     object sampleObject = GetSampleObject(); 
     FieldInfo[] testStructFields = typeof(Test).GetFields(); 

     foreach (FieldInfo testStructField in testStructFields) 
     { 
      if (testStructField.FieldType.IsArray) 
      { 
       // We can cast to ILIst because arrays implement it and we verfied that it is an array in the if statement 
       System.Collections.IList sampleObject_test1 = (System.Collections.IList)testStructField.GetValue(sampleObject); 
       // We can now get the first element of the array of Test2s: 
       object sampleObject_test1_Element0 = sampleObject_test1[0]; 

       // I hope this the FieldInfo that you want to get: 
       FieldInfo myValueFieldInfo = sampleObject_test1_Element0.GetType().GetField("MyValue"); 

       // Now it is possible to read and write values 
       object sampleObject_test1_Element0_MyValue = myValueFieldInfo.GetValue(sampleObject_test1_Element0); 
       Console.WriteLine(sampleObject_test1_Element0_MyValue); // prints 99 
       myValueFieldInfo.SetValue(sampleObject_test1_Element0, 55); 
       sampleObject_test1_Element0_MyValue = myValueFieldInfo.GetValue(sampleObject_test1_Element0); 
       Console.WriteLine(sampleObject_test1_Element0_MyValue); // prints 55 
      } 
     } 
    } 

    static object GetSampleObject() 
    { 
     Test sampleTest = new Test(); 
     sampleTest.Test1 = new Test2[5]; 
     sampleTest.Test1[0] = new Test2() { MyValue = 99 }; 
     object sampleObject = sampleTest; 
     return sampleObject; 
    } 
} 

[StructLayout(LayoutKind.Sequential)] 
public struct Test2 
{ 
    public int MyValue; 
} 

[StructLayout(LayoutKind.Sequential)] 
public struct Test 
{ 
    public byte Byte1; 
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] 
    public Test2[] Test1; 
} 

Ceci est la ligne la plus importante:

FieldInfo myValueFieldInfo = sampleObject_test1_Element0.GetType().GetField("MyValue"); 

Il devrait vous donner la FieldInfo dont vous parlez.

3

Qu'avez-vous exactement après? Il est pas FieldInfo pour les éléments du tableau ... vous pouvez itérer les valeurs en obtenant le tableau (comme Array) et itérer ... il suffit d'utiliser:

Array arr = (Array)field.GetValue(obj); 
+1

Je voudrais obtenir le FieldInfo de Test2 afin que je puisse définir des valeurs à partir de cette structure – SwDevMan81

+0

Pour Test1 oui, mais je le veux pour le tableau de Test2. Si c'est un tableau, je veux obtenir le FieldInfo du type tableau afin que je puisse faire field.SetValue (obj, valeur) pour la valeur Test1. – SwDevMan81

+0

Vous m'avez perdu quelque part entre Test1 et Test2 ... si vous voulez dire chaque instance dans le tableau, alors traitez chaque instance comme un objet ... alors vous avez GetType() etc. Ou utilisez arr.GetType(). GetElementType(). Mais il n'y a pas de champ qui pointe * dans le tableau. –

0

Le problème avec la technique de @ weiqure est que cela ne fonctionne que si le tableau contient déjà au moins un élément. Voici un moyen de trouver le type d'élément du tableau, si elle contient des éléments ou non:

bool GetArrayElementType(FieldInfo field, out Type elementType) 
{ 
    if (field.FieldType.IsArray && field.FieldType.FullName.EndsWith("[]")) 
    { 
     string fullName = field.FieldType.FullName.Substring(0, field.FieldType.FullName.Length - 2); 
     elementType = Type.GetType(string.Format("{0},{1}", fullName, field.FieldType.Assembly.GetName().Name)); 
     return true; 
    } 
    elementType = null; 
    return false; 
} 

Et voici comment vous pouvez utiliser cette fonction:

void Test(object targetObject, string fieldName) 
{ 
    FieldInfo field = targetObject.GetType().GetField(fieldName); 
    Type elementType; 
    bool success = GetArrayElementType(field, out elementType); 
} 
+0

En fait, cette partie est inutile: '&& field.FieldType.FullName.EndsWith (" [] ")' ... mais j'ai pensé que je l'ajouterais pour être complet. –

Questions connexes