我正在尝试使用一些固定字段来获取不安全结构的字段类型。固定字段FieldType不返回实际类型。
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public unsafe struct MyStruct
{
public UInt32 Field1;
public fixed sbyte Field2[10];
public UInt64 Field3;
}
void Test()
{
var theStruct = new MyStruct();
string output = "";
foreach (FieldInfo fi in theStruct.GetType().GetFields(BindingFlags.Public | BindingFlags.Instance))
{
output += fi.Name + ": " + fi.FieldType.ToString() + "\r\n";
}
}
输出:
Field1:System.UInt32
Field2:TestProjectNS.MyStruct+<Field2>e__FixedBuffer0
Field3:System.UInt64
我正在寻找Field2
告诉我sbyte
而不是TestProjectNS.MyStruct+<Field2>e__FixedBuffer0
答案 0 :(得分:6)
固定大小缓冲区的基础类型可以通过FixedBufferAttribute
检索,foreach (FieldInfo fi in typeof(MyStruct).GetFields(BindingFlags.Public | BindingFlags.Instance))
{
var attr = fi.GetCustomAttributes(typeof(FixedBufferAttribute), false);
if(attr.Length > 0)
output += fi.Name + ": " + ((FixedBufferAttribute)attr[0]).ElementType + "\r\n";
else
output += fi.Name + ": " + fi.FieldType + "\r\n";
}
应用于固定大小的缓冲区语句。
var type = typeof (MyStruct)
.GetField("Field2")
.GetCustomAttributes(typeof (FixedBufferAttribute), false)
.Cast<FixedBufferAttribute>()
.Single()
.ElementType;
或单字段短版本:
FixedBufferAttribute
作为CodeInChaos,我还需要反映它,但我确实有[StructLayout(LayoutKind.Sequential, Pack=1)]
public struct MyStruct
{
public uint Field1;
[FixedBuffer(typeof(sbyte), 10)]
public <Field2>e__FixedBuffer0 Field2;
public ulong Field3;
// Nested Types
[StructLayout(LayoutKind.Sequential, Size=10), CompilerGenerated, UnsafeValueType]
public struct <Field2>e__FixedBuffer0
{
public sbyte FixedElementField;
}
}
:
{{1}}
很棒的问题!
答案 1 :(得分:4)
TestProjectNS.MyStruct+<Field2>e__FixedBuffer0
是嵌套类型。它包含您想要的基础类型的单个字段。
因此,给定固定大小数组的FieldInfo
,您可以这样做:
Type bufferFieldType=fixedBufferFieldInfo.FieldType.GetFields(BindingFlags.Public | BindingFlags.Instance).Single().FieldType;
C#编译器生成的内容类似于以下内容:
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public unsafe struct MyStruct
{
[StructLayout(LayoutKind.Sequential, Pack = 1, Size=10)]
public struct Field2e__FixedBuffer0
{
public sbyte FixedElementField;
}
public UInt32 Field1;
public Field2e__FixedBuffer0 Field2;
public UInt64 Field3;
}
除了生成的struct的名称包含一些特殊字符,并且字段和嵌套类型都标记为安全关键字。
答案 2 :(得分:-1)
CodeInChaos是对的。另一种方法可以做到:
foreach (FieldInfo fi in theStruct.GetType().GetFields(BindingFlags.Public | BindingFlags.Instance))
{
if (fi.FieldType.IsNested)
{
output += fi.Name + ": " +
fi.FieldType.GetFields()[0].FieldType.ToString() + "\r\n";
}
else
{
output += fi.Name + ": " + fi.FieldType.ToString() + "\r\n";
}
}