在C#中用什么来作为算法参数:static、const还是readonly?

3

我有一些类,它们的方法实现了科学数值算法。

例如,一个类实现了径向基函数并需要一些参数。目前,这些参数是这样的:

public class Interpolator {

    // Free parameters
    static int LAYERS = 6;
    static int MINIMUM_NEIGHBORS = 1;
    static double SEARCH_RADIUS = 20;
    static double START_RADIUS = 100;

    (...)
}

这里的想法是这些参数将通过实验确定,理想情况下不应更改,甚至不应通过配置进行更改。
所以问题是:哪种方式是“正确”的声明方式?它们实际上应该是static吗?难道它们不应该是const吗?在C#中,通常如何实现这种(相当常见)模式,以符合良好的实践标准?
感谢阅读!
3个回答

8

这里的想法是这些参数将通过实验确定,理想情况下不应该更改,甚至不通过配置文件。

只需将它们声明为常量const。由于常量默认为静态,您可以使用类名访问它们。

如果您将它们定义为静态变量,则也可以修改它们。

public class Interpolator
{
    const int LAYERS = 6;
    const int MINIMUM_NEIGHBORS = 1;
    const double SEARCH_RADIUS = 20;
    const double START_RADIUS = 100;
}

非常有用的信息。但是这些变量是私有的,仅在此类方法内使用。 - heltonbiker
@heltonbiker,如果它们是私有的,则无法在类外部访问它们,但将它们设置为const仍然可以避免意外修改任何这些变量。 - Habib
不错,这就是我们的想法。即使这个项目完全是内部编程完成的,你提到的这些意外(有缺陷的)修改随时都可能发生。谢谢! - heltonbiker

1

简明实用的答案如下:

readonly : 如果初始化后不需要更改,请使用readonly。

static : 如果需要从其他程序集访问,请使用static。

const : 如果前两个问题的答案都是否定的,请使用const。


这并不完全正确。readonly staticconst不是一回事。如果是readonly static,那么它是一个变量,并且占用内存中的位置。它也可以是非文字值,甚至可以在运行时生成(只要在初始化后没有更改)。const表示它是一个编译时常量,因为它不会创建内存中的位置;文字值被嵌入到标识符使用的每个地方。 - Servy

1
为了使用“不会改变的值”,您可以声明字段为conststatic readonly
public class Interpolator 
{
  // Free parameters
  static readonly int LAYERS = 6;
  const int MINIMUM_NEIGHBORS = 1;
}

为了决定使用哪种方法,我使用以下标准:
  • 如果它只在此程序集中访问(在Visual Studio中的此项目),请使用const
  • 如果可能会被其他程序集访问,请使用static readonly

改进您的示例:

public class Interpolator 
{
  // Free parameters
  public static readonly int LAYERS = 6;
  internal const int MINIMUM_NEIGHBORS = 1; // internal means public to this assembly but private to other assemblies.
  private const double SEARCH_RADIUS = 20;
}

为什么要做出这样的区分? 当编译器在表达式中发现一个 const 字段时,它会将该字段替换为其值并进行编译。这非常高效。
int a = 5 * Interpolator.SEARCH_RADIUS;

is compiled as:

int a = 100;

但是想象一下,您在一个(.dll)程序集中将Interpolator.SEARCH_RADIUS定义为一个const,并从另一个(.exe)程序集中使用它。
public const double SEARCH_RADIUS = 20;

如果您将来更改了定义,则为:

如果在未来您更改了定义,则为

private const double SEARCH_RADIUS = 10;

重新编译 (.dll) 程序集。如果您不重新编译 (.exe) 程序集,则它仍将使用 a==100,因为 SEARCH_RADIUS = 20 是 .exe 编译期间使用的值。

如果您已定义

public static readonly double SEARCH_RADIUS = 20;

在.dll文件中,当您将值更改为10并仅重新编译(.dll)程序集时,另一个(.exe)程序集会自动获取更改,而无需重新编译。

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