简体   繁体   English

用C#反射修改类中的私有常量字段

[英]Reflection in C# to modify a private constant field in a class

I have the following class: 我有以下课程:

class RuleParser
{
   private const String FILE = "./rules/DetectionStrategies.xml";
   .
   .
   .
}

Now in my test project I want to set the FILE constant to another value. 现在,在我的测试项目中,我想将FILE常量设置为另一个值。 How can I achieve that using Reflection? 如何使用Reflection实现这一目标?

You fell into a trap... 你陷入了困境......

const != readonly

If it was read-only, you could do that, but const means compile-time constant, which compilers in turn embed into the resulting program. 如果它是只读的,你可以这样做,但const意味着编译时常量,然后编译器嵌入到生成的程序中。 Hence what you do won't have an effect on pretty much any program, yours or others'. 因此,你所做的事情几乎不会影响任何程序,你的或其他程序。

Add this to your config file: 将其添加到您的配置文件中:

<appSettings>
    <add key="DetectionStrategies" value="./rules/DetectionStrategies.xml" />
</appSettings>

But I would have it as a property with a private setter instead like such: 但我会把它作为一个私人安装者的财产,而不是这样:

class RuleParser
{
    private string _file = string.Empty;
    private string File 
    {
        get 
        {
            if(string.IsNullOrEmpty(_file))
                _file = ConfigurationManager.AppSettings["DetectionStrategies"];
            return _file;
        }
        private set;
    }
}

You need to remember to include the System.Configuration . 您需要记住包含System.Configuration

EDIT: Since it has to be a compile time constant when you're assigning values to a const I removed that and only kept the "property" with private set solution. 编辑:因为它必须是一个编译时常量,当你将值赋值给const我删除了它并且只保留了“属性”与私有集解决方案。

EDIT 2: The important part of this is that you should only use const for true constants, configurable values should be configurable and a good place for that is the config file. 编辑2:这一点的重要部分是你应该只使用const作为真正的常量,可配置的值应该是可配置的,一个好的地方就是配置文件。 Although, you don't have to use the config file, you could as well write your own configuration class that goes against a database instead or against a database with the configuration file as fallback. 虽然,您不必使用配置文件,但您也可以编写自己的配置类,而不是编写数据库,或者使用配置文件作为回退编写数据库。 I might be thinking that you want to use a static variable and not const but that depends on how you're using the variable and in what context. 我可能认为你想要使用static变量而不是const但这取决于你如何使用变量以及在什么上下文中。

Geez dude, do you know what constant means? Geez老兄,你知道什么是常数吗? You can't change it. 你无法改变它。 I think that compilers don't even compile references to constants, they just compile the actual value, so they wouldn't even notice if the value actually changed. 我认为编译器甚至不编译对常量的引用,它们只是编译实际值,所以他们甚至不会注意到值是否实际发生了变化。

Instead of trying to change a const in runtime, (or a readonly or whatever), I'd suggest you consider to make some design changes to improve the testability of your code. 我建议您考虑进行一些设计更改以提高代码的可测试性,而不是尝试在运行时(或者readonly或其他)中更改const

Some simple examples would be: 一些简单的例子是:

  1. Move the value to App.Config so that the test can have different values. 将值移动到App.Config以便测试可以具有不同的值。
  2. Abstract the file path from the RuleParser class by providing it in the constructor. 通过在构造函数中提供它来从RuleParser类中提取文件路径。 Either by specifying the path itself, or by providing some interface (eg IFileParserConfig ) that would provide the value in runtime. 通过指定路径本身,或者通过提供一些将在运行时提供值的接口(例如IFileParserConfig )。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM