如何访问结构体(如c#中的数组)的成员
本文关键字:何访问 数组 成员 访问 结构体 | 更新日期: 2023-09-27 18:02:44
假设我有一个结构体,它有100多个复杂名称的元素。我用ref将struct类型的结构体传递给函数,如下所示:
void Foo(ref mystruct a)
{
"I want to modify members or fields of struct a, like this:
a[0] = 10;
a[100] = 11;"
}
谢谢!
也许您应该重新检查您对数据结构的选择。也许一本字典更合适?
这是一个奇怪的请求,因为你期望字段的顺序是有意义的,但我怀疑你可以通过反射或TypeDescriptor来做到这一点。
/* yeah, probably not a good idea.
public void Foo(ref MyStruct a)
{
TypeDescriptor.GetProperties(a)[0].SetValue(a, 10);
}
*/
虽然您可以使用struct LayoutKind属性强制简单类型像"C" Union一样共享内存,但您仍然不能使数组与简单类型共享内存,因为ref类型(又名垃圾收集类型)不能与该属性一起工作。像结构体的memset这样的C快捷方式的概念无论如何都不能映射到c#中,因为c#是一种安全的语言。事实上,这是一件好事。许多错误都来自于这种内存寻址快捷方式。
如果你想模拟这种行为,创建一个类的属性映射到一个后备数组的特定成员,但是,为什么要这样做?c#中有更好的数据结构来满足你的需求,比如List, SortedList, Dictionary, Map, Stack等等,它们都是安全的。
你可以在。net中这样做,但正如其他几个人已经发布的那样:不要这样做。
的一些代码a.GetType().GetProperties() [0].SetValue (a, newvalue, null);
编辑:不这样做的几个理由:
订单不保证!
如果没有属性会发生什么
所以:不要这样做!
我可能会下地狱,但是…
显然很可怕,不推荐,只有当你的字段都是默认布局的整型时才有效…
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));
}
}