[英]How could I set a value to a fieldInfo with jagged array type through reflection?
I have a fieldInfo of the type TileType[][]. 我有一个类型为TileType [] []的fieldInfo。 How could I set a value to this fieldInfo?
如何为该fieldInfo设置值?
internal static class Program
{
private struct Data
{
public enum TileType : byte
{
Passable,
Unpassable
}
public TileType[][] TileTypes;
}
private static T LoadData<T>(string[] values)
{
var t = (T)Activator.CreateInstance(typeof(T));
object boxed = t;
FieldInfo field = boxed.GetType().GetField("TileTypes"); // I get TileType[][] field here.
IList<IList<string>> tilesMatrix = new string[values.Length][];
for (byte x = 0; x < values.Length; x++)
{
tilesMatrix[x] = new string[values.Length];
tilesMatrix[x] = values;
}
SetValuesToJaggedArray<object, byte[], byte>(boxed, field, tilesMatrix);
return (T)boxed;
}
private static void SetValuesToJaggedArray<T, TTarget, TTargetElement>(T obj, FieldInfo field, IList<IList<string>> values)
{
var objs = new Array[values.Count];
for (ushort x = 0; x < values.Count; x++)
{
var ar = new TTarget[values.Count];
var arobjs = new object[values.Count];
for (ushort y = 0; y < values.Count; y++)
{
var elements = new List<TTargetElement>();
for (ushort z = 0; z < values[y].Count; z++)
{
var element = (TTargetElement)Convert.ChangeType(values[y][z], typeof(TTargetElement), CultureInfo.InvariantCulture);
elements.Add(element);
}
object bElts = elements.ToArray();
var value = (TTarget)bElts;
arobjs[y] = value;
}
Array.Copy(arobjs, ar, values.Count);
objs[x] = new TTarget[values.Count];
Array.Copy(ar, objs[x], values.Count);
}
object b = objs;
field.SetValue(obj, b); // Exception here!
}
static void Main(string[] args)
{
Data d = LoadData<Data>(new string[4] { "0", "1", "2", "3" });
}
}
I got exception from the line field.SetValue(obj, b); 我从line field.SetValue(obj,b);中获得了异常。 because I don't have a clue how to set a value there.
因为我不知道如何在此处设置值。 Any help appreciated.
任何帮助表示赞赏。
Fixed solution, thx to Mitch for answer: 固定解决方案,谢谢米奇:
internal static class Program
{
public struct Data
{
public enum TileType : byte
{
Passable,
Unpassable,
Water,
Empty
}
public TileType[][] TileTypes;
}
private static T LoadData<T>(string[][] values)
{
var t = (T)Activator.CreateInstance(typeof(T));
object boxed = t;
FieldInfo field = boxed.GetType().GetField("TileTypes"); // I get TileType[][] field here.
SetValuesToJaggedArray<object, byte>(boxed, field, values);
return (T)boxed;
}
private static void SetValuesToJaggedArray<T, TTargetElement>(T obj, FieldInfo field, string[][] values)
{
var objs = new TTargetElement[values.Length][];
for (ushort x = 0; x < values.Length; x++)
{
var elements = new TTargetElement[values.Length];
for (ushort y = 0; y < values.Length; y++)
{
var element = (TTargetElement)Convert.ChangeType(values[x][y], typeof(TTargetElement), CultureInfo.InvariantCulture);
elements[y] = element;
}
objs[x] = elements;
}
field.SetValue(obj, objs);
}
static void Main()
{
var matrix = new string[4][];
matrix[0] = new[] { "0", "1", "2", "3" };
matrix[1] = new[] { "1", "2", "3", "0" };
matrix[2] = new[] { "2", "3", "0", "1" };
matrix[3] = new[] { "3", "0", "1", "2" };
var d = LoadData<Data>(matrix);
const string whiteSpace = " ";
for (byte x = 0; x < d.TileTypes.Length; x++)
{
for (byte y = 0; y < d.TileTypes.Length; y++)
Console.Write(d.TileTypes[x][y] + whiteSpace);
Console.WriteLine();
}
Console.ReadKey();
}
}
If you cut through the rest of your example, you are left with the following: 如果您没有完成本示例的其余部分,则将剩下以下内容:
struct Data
{
byte[][] TitleTypes;
}
static void Main(string[] args)
{
var d = new Data();
var field = typeof(Data).GetField("TitleTypes");
var newValue = new byte[5];
// This line fails because you are setting a field of type byte[][] with
// a value of byte[]
field.SetValue(d, newValue);
}
Either set a specific index into the array or set TitleTypes
with a value of the appropriately jagged array. 在数组中设置特定的索引,或者使用适当的锯齿状数组的值设置
TitleTypes
。 See Setting value in an array via reflection for details on why and how. 有关原因和方式的详细信息,请参见通过反射在数组中设置值 。
static void Main(string[] args)
{
var d = new Data();
var field = typeof(Data).GetField("TitleTypes");
// set to index 0
var newValue = new byte[5];
var arrTarget = (byte[][])field.GetValue(d);
arrTarget[0] = newValue;
// replace entire array
var newArray = new byte[5][];
field.SetValue(d, newArray);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.