Ron*_*ein 111 c# reflection field readonly
我想知道,因为可以使用反射完成很多事情,我可以在构造函数完成执行后更改私有只读字段吗?
(注意:只是好奇心)
public class Foo
{
private readonly int bar;
public Foo(int num)
{
bar = num;
}
public int GetBar()
{
return bar;
}
}
Foo foo = new Foo(123);
Console.WriteLine(foo.GetBar()); // display 123
// reflection code here...
Console.WriteLine(foo.GetBar()); // display 456
Run Code Online (Sandbox Code Playgroud)
Phi*_*ert 144
您可以:
typeof(Foo)
.GetField("bar",BindingFlags.Instance|BindingFlags.NonPublic)
.SetValue(foo,567);
Run Code Online (Sandbox Code Playgroud)
Jon*_*eet 52
显而易见的是尝试它:
using System;
using System.Reflection;
public class Test
{
private readonly string foo = "Foo";
public static void Main()
{
Test test = new Test();
FieldInfo field = typeof(Test).GetField
("foo", BindingFlags.Instance | BindingFlags.NonPublic);
field.SetValue(test, "Hello");
Console.WriteLine(test.foo);
}
}
Run Code Online (Sandbox Code Playgroud)
这很好用.(Java有不同的规则,有趣的是 - 你必须明确地设置它Field
是可访问的,并且它只适用于实例字段.)
And*_*eas 12
我同意其他答案,因为它通常起作用,尤其是E.Lippert的评论,这不是记录在案的行为,因此不是面向未来的代码.
但是,我们也注意到了另一个问题.如果您在具有受限权限的环境中运行代码,则可能会出现异常.
我们刚刚遇到一个案例,我们的代码在我们的机器上运行良好,但是我们收到了VerificationException
代码在受限环境中运行的时间.罪魁祸首是对只读字段的设定者的反思.当我们删除该字段的readonly限制时,它工作.
小智 5
您问为什么要像这样打破封装。
我使用实体辅助类来水合实体。这使用反射来获取新空实体的所有属性,并将属性/字段名称与结果集中的列相匹配,并使用 propertyinfo.setvalue() 设置它。
我不希望其他人能够更改该值,但我也不想花费所有精力为每个实体自定义代码水合方法。
我的许多存储过程返回的结果集并不直接对应于表或视图,因此代码生成 ORM 对我没有任何作用。
小智 5
不要这样做。
我刚刚花了一天时间修复一个超现实的错误,其中对象可能不是它们自己声明的类型。
修改只读字段一次有效。但如果你尝试再次修改它,你会遇到这样的情况:
SoundDef mySound = Reflection_Modified_Readonly_SoundDef_Field;
if( !(mySound is SoundDef) )
Log("Welcome to impossible-land!"); //This would run
Run Code Online (Sandbox Code Playgroud)
所以不要这样做。
这是在 Mono 运行时(Unity 游戏引擎)上。
归档时间: |
|
查看次数: |
45961 次 |
最近记录: |