为什么反射可以在C#中访问类的受保护/私有成员?
这对班级来说是不安全的,为什么反思会给予这样的权力?这是anti-pattern吗?
答案 0 :(得分:22)
会员辅助功能不是安全功能。这是为了保护程序员免受他或她自己的伤害。它有助于实现封装,但它绝不是安全功能。
使用反思非常繁琐,以至于人们通常不会自愿使用它来访问非公共成员。它也很慢。反射通常仅用于特殊情况。然而,没有什么可以完全保护人类的愚蠢,如果有人想滥用反思,他可以很容易地做到,但即使没有反射API,他们也可以实现同样的事情(如果他们完全信任,那就是)如果他们确定不够。
答案 1 :(得分:19)
这对于远程处理,序列化,实现等方案是必要的。您不应盲目使用它,但请注意,这些工具始终在任何系统中都可用(实际上,通过寻址记忆直接)。反思简单地将其形式化,并将控制和检查放在路上 - 您没有看到它,因为您可能正在以“完全信任”运行,因此您已经比受保护的系统更强大。
如果您在部分信任中尝试此操作,您将看到对内部状态的更多控制。
这是一种反模式吗?
仅当您的代码使用不当时。例如,请考虑以下内容(对WCF数据协定有效):
[DataMember]
private int foo;
public int Foo { get {return foo;} set {foo = value;} }
WCF支持这个不正确吗?我怀疑没有...有多种情况下你想要序列化不属于公共API的东西,而没有单独的DTO。同样,如果您选择,LINQ-to-SQL将实现为私有成员。
答案 2 :(得分:-1)
反射对于调试器来说是绝对必要的。想象一下,您正在单步执行程序,无法查看私有变量的值。这可能就是为什么反射在.NET和Java中工作的原因,使调试变得非常简单。
如果我们不需要调试器,那么我可以想象,OOP的精神会更多地限制反射。