배열 필드의 FieldInfo를 어떻게 얻습니까?
-
10-07-2019 - |
문제
구조물 내에서 배열 값의 필드 정보를 얻으려고 노력하고 있습니다. 지금까지 나는 다음을 가지고 있지만, 내가 원하는 정보를 얻는 방법을 보지 못합니다.
[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
}
}
그래서 내가했다면 :
Type array_type = struct_field.FieldType.GetElementType();
이것은 Test2 유형을 반환하지만 배열의 유형을 원하지 않습니다. 해당 구조의 FieldInfo 또는 필드를 원해서 그 안에 값을 설정할 수 있습니다.
해결책
초기 정답에 대해 죄송합니다. 나는 내 자신의 test2 유형을 만들기에는 너무 게으르기 때문에 대신 문자열을 사용했습니다. 다음은 정답입니다 (희망적으로) :
나는 당신이 다음 코드로하고 싶은 일을했습니다.
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;
}
이것은 가장 중요한 줄입니다.
FieldInfo myValueFieldInfo = sampleObject_test1_Element0.GetType().GetField("MyValue");
그것은 당신이 말하는 FieldInfo를 주어야합니다.
다른 팁
당신은 정확히 무엇입니까? 거기 ~이다 아니요 FieldInfo
배열의 항목의 경우 ... 배열을 가져 와서 값을 반복 할 수 있습니다. Array
) 그리고 반복 ... 그냥 사용하십시오 :
Array arr = (Array)field.GetValue(obj);
@weiqure 기술의 문제점은 배열에 이미 하나 이상의 요소가있는 경우에만 작동한다는 것입니다. 요소가 포함되어 있는지 여부에 관계없이 배열의 요소 유형을 찾는 방법은 다음과 같습니다.
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;
}
그리고 다음은 그 기능을 사용하는 방법입니다.
void Test(object targetObject, string fieldName)
{
FieldInfo field = targetObject.GetType().GetField(fieldName);
Type elementType;
bool success = GetArrayElementType(field, out elementType);
}
제휴하지 않습니다 StackOverflow