【问题标题】:Reflection in C# to modify a private constant field in a classC# 中的反射以修改类中的私有常量字段
【发布时间】:2011-01-01 21:33:48
【问题描述】:

我有以下课程:

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

现在在我的测试项目中,我想将 FILE 常量设置为另一个值。如何使用反射来实现这一点?

【问题讨论】:

  • 你为什么不使用配置文件来存储这种值?
  • 不知道配置文件是什么意思?每个 .net 项目都有一个配置文件。它是 web.config 或 app.config,具体取决于项目类型。
  • 我不知道有类似配置文件的东西

标签: c# .net reflection


【解决方案1】:

你掉进了陷阱……

const != readonly

如果它是只读的,你可以这样做,但const 表示 compile-time 常量,编译器又将其嵌入到生成的程序中。因此,您所做的几乎不会对您的或其他人的任何程序产生影响。

【讨论】:

  • 从技术上讲,仍然可以更改它。即使它是由编译器设置的,您也可以在二进制文件中找到该变量并在那里进行更改。
  • 是的......因此我说“你所做的几乎不会对任何程序产生影响”,而不是“这是不可能的”。从技术上讲,如果该程序是使用没有内联字段值的相当愚蠢的编译器编译的,那么它对程序产生影响......因此“几乎”。 :)
【解决方案2】:

将此添加到您的配置文件中:

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

但我会将它作为具有私有设置器的属性而不是像这样:

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

您需要记住包含System.Configuration

编辑:因为当你为 const 赋值时它必须是一个编译时间常数,所以我删除了它,只保留了私有设置解决方案的“属性”。

编辑 2: 重要的部分是您应该只将 const 用于真正的常量,可配置的值应该是可配置的,配置文件是一个很好的地方。虽然,您不必使用配置文件,但您也可以编写自己的配置类来代替数据库或使用配置文件作为后备的数据库。我可能会认为您想使用 static 变量而不是 const 但这取决于您如何使用该变量以及在什么上下文中。

【讨论】:

  • Ehm,const 的本质是它是 100% 的 const。除了 C# 常量之外,您不能为它分配任何值。
  • @Dykam:我以为是这样,但不是 100%……我加了一句话。
  • 没错,但我认为他的主要问题是他没有使用配置文件来获取应该可配置的参数。如果他决定使用readonly 或属性对我来说并不重要。
【解决方案3】:

我建议您考虑进行一些设计更改以提高代码的可测试性,而不是尝试在运行时更改 const(或 readonly 或其他)。

一些简单的例子是:

  1. 将值移动到App.Config,以便测试可以有不同的值。
  2. 通过在构造函数中提供 RuleParser 类来抽象文件路径。通过指定路径本身,或者通过提供一些接口(例如IFileParserConfig)来在运行时提供值。

【讨论】:

    【解决方案4】:

    老兄,你知道常量是什么意思吗?你不能改变它。我认为编译器甚至不编译对常量的引用,他们只是编译实际值,所以他们甚至不会注意到值是否实际发生了变化。

    【讨论】:

    • 如果它的措辞不那么崇高,我会赞成的。另外,关于引用类型:stackoverflow.com/questions/1109805/…
    • 是的,当然,您不能跳过对数组的引用。但是我在 Reflector 中浏览时看到了许多使用原始常量值而不是字段引用的实例。
    • 我认为 Dykam 也指的是“Geez dude”位。我从您之前的回答和 cmet 中知道您有有趣的知识和经验,为什么要以居高临下的方式破坏它?
    • 英语不是我的母语,我完全以为我在搞笑:)
    猜你喜欢
    • 2012-01-23
    • 2010-11-26
    • 2013-01-26
    • 1970-01-01
    • 2020-05-01
    • 2011-05-29
    • 1970-01-01
    • 2011-10-06
    • 2014-02-22
    相关资源
    最近更新 更多