Comment accéder aux membres d’une structure comme un tableau en C #?

Disons que j’ai une structure avec plus de cent éléments avec des noms complexes. Et je passe une struct du type struct décrit à une fonction utilisant ref, comme ceci:

void Foo(ref mystruct a) { "I want to modify members or fields of struct a, like this: a[0] = 10; a[100] = 11;" } 

Merci!

Peut-être devriez-vous réexaminer votre choix de structure de données. Peut-être qu’un dictionnaire conviendrait mieux?

C’est une requête étrange, car vous vous attendez à ce que l’ordre des champs soit significatif , mais je suppose que vous pouvez le faire via Reflection ou le TypeDescriptor.

Je voudrais réviser mon exemple de code ci-dessous pour utiliser les noms de propriété appropriés avec des constantes, mais si vous connaissez les noms de propriété, appelez simplement les propriétés et enregistrez-vous de la surcharge de reflection. Sinon, utilisez un dictionnaire avec des constantes.

 /* yeah, probably not a good idea. public void Foo(ref MyStruct a) { TypeDescriptor.GetProperties(a)[0].SetValue(a, 10); } */ 

Bien que vous puissiez utiliser l’atsortingbut struct LayoutKind pour forcer les types simples à partager la mémoire comme une union “C”, vous ne pouvez toujours pas créer de mémoire pour un tableau avec des types simples, car les types ref (types ordonnés) ne fonctionnent pas avec l’atsortingbut. Le concept de raccourcis C, comme memset d’une structure, ne correspond en aucune manière à C #, car C # est un langage sûr. En fait, c’est une bonne chose. Beaucoup de bugs proviennent de ce type de raccourcis d’adressage mémoire.

Si vous souhaitez simuler ce problème, créez une classe avec des propriétés mappées à des membres spécifiques d’un tableau de sauvegarde, mais pourquoi ne pas procéder ainsi? Il existe de bien meilleures structures de données adaptées à vos besoins en C #, telles que Liste, SortedList, Dictionnaire, Carte, Pile, etc., qui sont sûres.

Je vais probablement brûler en enfer, mais …

De toute évidence horrible et non recommandé et ne fonctionne que si vos champs sont tous ints avec la disposition par défaut …

 internal class Program { private struct MyStruct { //Must be all Int32 public int Field1, Field2, Field3; } private static void Main() { MyStruct str = new MyStruct {Field1 = 666, Field2 = 667, Field3 = 668}; int[] array = ToArray(str); array[0] = 100; array[1] = 200; array[2] = 300; str = FromArray(array); } private static int[] ToArray(MyStruct str) { IntPtr ptr = IntPtr.Zero; try { int size = GetInt32ArraySize(str); int[] array = new int[size]; ptr = Marshal.AllocHGlobal(size); Marshal.StructureToPtr(str, ptr, true); Marshal.Copy(ptr, array, 0, size); return array; } finally { Marshal.FreeHGlobal(ptr); } } private static MyStruct FromArray(int[] arr) { IntPtr ptr = IntPtr.Zero; try { MyStruct str = new MyStruct(); int size = GetInt32ArraySize(str); ptr = Marshal.AllocHGlobal(size); Marshal.Copy(arr, 0, ptr, size); str = (MyStruct)Marshal.PtrToStructure(ptr, str.GetType()); return str; } finally { Marshal.FreeHGlobal(ptr); } } private static int GetInt32ArraySize(MyStruct str) { return Marshal.SizeOf(str) / Marshal.SizeOf(typeof(Int32)); } } 

Vous pouvez le faire dans .NET MAIS, comme plusieurs autres l’ont déjà publié: NE LE FAITES PAS.

Du code

 a.GetType().GetProperties() [0].SetValue (a, newvalue, null); 

EDIT: plusieurs raisons de ne pas le faire:

  • la commande n’est pas garantie!

  • que se passe-t-il lorsqu’il n’y a pas de propriétés?

  • que se passe-t-il avec les propriétés en lecture seule?

Encore une fois: NE FAITES PAS CELA!