我可以在C#中改变常量的值吗?

17
我需要一个针对旧版 .NET dll 的hack,因为该dll无法重新编译。例如使用反射等方法的某些hack。

11
哦,想象一下将常数变为非常数所带来的混乱。这甚至可能会让猫王复活。 - Fredrik Mörk
1
你需要将该值更改以在 DLL 内部使用,还是仅在被 DLL 外部引用时使用? - Sam Holder
是的,我可以想象。这就是为什么我在谈论黑客的原因。 - Durika
希望你不会因为我的玩笑而生气;我真的应该加上一个笑脸。这是一个很好的问题,有很多有趣的含义需要思考(所以我点了赞)。 - Fredrik Mörk
5个回答

17
如果程序集未签名,则您可能能够将其反汇编并修改IL并重新编译,或将其反汇编为源代码,修改并重新编译。要将其反汇编到源代码,可以使用Reflector(警告-不再免费)和Dennis Bauers插件,或者可以使用Reflexil作为Reflector的另一个插件,它带有完整的VB/C#编辑器和Intellisense,可直接从Reflector注入代码。

要将其反汇编到IL,您可以使用ILSpy反汇编程序或MSILDissasembler

正如其他人指出的那样,您需要仔细考虑这样做的影响。 它可能会产生比您意识到的更多的连锁反应。

另一件非常重要的事情是,如果常量被其他引用您正在重新编译的dll的dll使用,那么这些dll将无法在未重新编译的情况下看到常量的新值。这是因为当某些东西被定义为常量时,“常量”值作为优化(因此每次使用时不必在引用的dll中查找)在构建时嵌入到引用的dll中,因此对“常量”值的更改实际上从未在引用“常量”的任何库中看到。有关更多详细信息,请参见此问题和答案。


JustDecompile是免费的,并支持Reflexil。 - imlokesh

11

补充Stecya的回答:
常量变量的值将在使用它的任何地方插入。这意味着所有引用您的旧版程序集并使用该常量的程序集也需要重新编译,以反映常量变量的更新值。顺便说一下,这也是通过公共接口以普通属性形式公开常量值的好处所在。


4
这是其中一篇我希望能够点赞两次的回答;一次点赞是因为指出了需要重新编译使用该常量的代码,另一次是因为 "不要直接暴露常量" 的建议。 - Fredrik Mörk
1
是的,始终通过属性公开常量加1。 - Sam Holder

3

由于const是在编译时计算得出的,因此您无法更改它。唯一的方法是修改该传统程序集以更改该const字段。


3

反射无法起作用,因为该值是硬编码到应用程序的字节代码中,无法通过反射进行修改。

如果它没有经过代码签名,请使用十六进制编辑器或ILDasm修改常量的值。

如果已经进行了代码签名,则无法解决此问题,除非放弃代码签名。

如果您正在编辑已编译的程序集,请小心。您也许无法这样做的原因有法律上的原因。


1

编译期间常量值被替换为字面常量,因此您很难在不重新编译的情况下更改它


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接