我试图通过反思设置一个值。我创建了这个小测试程序
struct headerIndexes
{
public int AccountNum{ get; set; }
public int other { get; set; }
public int items { get; set; }
}
static void Main(string[] args)
{
headerIndexes headers = new headerIndexes();
headers.AccountNum = 1;
Console.WriteLine("Old val: {0}", headers.AccountNum);
foreach (var s in headers.GetType().GetProperties())
{
if (s.Name == "AccountNum")
s.SetValue(headers, 99, null);
}
Console.WriteLine("New val: {0}", headers.AccountNum);
Console.ReadKey();
}
在程序中我正确地看到它执行命令s.SetValue(headers, 99, null);
但是当运行setValue时,headers.AccountNum的值保持为1。
我错过了一个明显的步骤吗?
答案 0 :(得分:3)
我认为标题可能会被装入一个新对象,因为它是一个结构,然后一旦SetValue返回,该对象就会收集垃圾。将其更改为班级,看看问题是否消失。
答案 1 :(得分:1)
SetValue
期待object
导致headers
上的装箱操作。由于headers
是struct
,因此它是值类型。因此,会制作副本,您要修改的内容是盒装对象,而不是headers
。
您应该认真考虑避免使用可变值类型。
来自Eric Lippert:
这是可变值类型为恶的另一个原因。尝试始终使值类型不可变。
答案 2 :(得分:1)
您也可以使用未装箱的struct版本
object unboxedHeader = headers;
s.SetValue(unboxedHeader,99,null);
struct headerIndexes
{
public int AccountNum{ get; set; }
public int other { get; set; }
public int items { get; set; }
}
static void Main(string[] args)
{
headerIndexes headers = new headerIndexes();
headers.AccountNum = 1;
Console.WriteLine("Old val: {0}", headers.AccountNum);
object unboxedHeader=headers;
foreach (var s in headers.GetType().GetProperties())
{
if (s.Name == "AccountNum")
s.SetValue(unboxedHeader, 99, null);
}
Console.WriteLine("New val: {0}", headers.AccountNum);
Console.ReadKey();
}