【问题标题】:How to declare a local constant in C#?如何在 C# 中声明一个局部常量?
【发布时间】:2010-01-13 05:58:37
【问题描述】:

如何在 C# 中声明一个局部常量?

就像在 Java 中一样,您可以执行以下操作:

public void f(){
  final int n = getNum(); // n declared constant
}

如何在 C# 中做同样的事情?我尝试了readonlyconst,但似乎都没有。

任何帮助将不胜感激。

谢谢。

【问题讨论】:

  • 这是我在短时间内使用 C# 时最烦人的遗漏。为了我自己的安全、理智和可读性,我一直在 C++ 中的局部变量上使用 const。
  • @MauricioScheffer,感谢您的链接。虽然现在如果我必须为 .NET 编写一些东西,我肯定会使用 F#。 :-)

标签: c# immutability readonly local-variables


【解决方案1】:

在 C# 中,不能创建从方法中检索的常量。

编辑:死链接 http://msdn.microsoft.com/en-us/library/e6w8fe1b(VS.71).aspx

这个文档应该有助于: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/const

常量表达式是可以在 编译时间。

【讨论】:

  • 好吧,这很糟糕。 ://
  • 残酷。我不仅应该被支持,它应该是默认的。
  • finalconst 有不同的含义。在 C# 中,const 值必须在编译时已知。真正的问题是 C# 不支持本地 readonly 变量,这太糟糕了,因为它们很方便。
  • @Nick,在 c++ 中,本地常量不必在编译时就知道。
【解决方案2】:

将您的局部变量声明为迭代变量。迭代变量是只读的 (你没有要求一个漂亮的解决方案)。

public void f() 
{
  foreach (int n in new int[] { getNum() }) // n declared constant
  {
    n = 3; // won't compile: "error CS1656: Cannot assign to 'n' because it is a 'foreach iteration variable'"
  }
}

【讨论】:

  • 很高兴知道,但上帝保证,永远不会这样做。
  • 那是金子)这个黑客太丑了,我什至没有考虑过。我肯定会用它(作为sn-p)来检查我的代码,你知道的,临时将var index=GetNum() 更改为foreach 以强制编译器检查我的代码。
  • 天哪。当我认真考虑使用这个黑客时,我仍然把头撞在桌子上。多么肮脏的一个;-)
【解决方案3】:

我不确定为什么 readonlyconst 不适合您,因为这些是您需要的关键字。如果您有文字(数组文字除外),则使用const,否则使用readonly

public void f()
{
    const int answer = 42;
}

private readonly int[] array = new int[] { 1, 2, 3, 4 };
private readonly DateTime date = DateTime.Now;
public void g()
{
    Console.WriteLine(date.ToString());   
}

readonly 仅适用于类级别(也就是说,您只能将其应用于字段)。同样由于 const 需要文字,它本质上是静态的,而 readonly 字段可以是静态的或实例的。

【讨论】:

  • 需要注意的是,创建引用类型的只读实例仅意味着引用本身不能更改;对象仍然可以正常修改(除非类型是不可变的,比如String)。
  • 你的问题的答案很简单——在给定的例子中没有一个(const,readonly)可以工作。
【解决方案4】:

有一种解决方法需要 ReSharper。您无法获取只读本地人,但您至少可以检测变异的本地人并为它们着色。

使用字体和颜色项Resharper 可变局部变量标识符

对我来说,我将局部变量涂成灰色,然后我为变异变量选择了粗体白色(这是一个深色主题)。这意味着与常规变量相比,多次写入的任何变量都显示得更亮。然后,您可以尽您所能避免使用变异变量,或者如果该方法确实需要一个,那么它至少会被突出显示。

【讨论】:

  • 它对我不起作用。它仅将循环计数器显示为不可变,其他一切都是可变的,无论写入多少次。我猜我的 Resharper 太旧了 :-)
  • @Xan-KunClark-Davis 它没有显示什么是可变的,它显示了什么是变异的。任何只写一次的东西都会看起来很正常。写入两次或多次的任何内容都将突出显示。 (哦,我猜你说“不管写多少”)。你确定吗?类似int x = 5; x = 3;,x 应该改变颜色。我想这可能是版本,是的。
  • @Sahuagin 是的,我得到了你必须反转它的部分,所有本地人都会得到高亮显示,所有可变数据都会再次“正常化”,但它仍然不会改变颜色。我会再次尝试一个干净的项目。
  • 好的,我打开了一个新的工作区,又试了一次,成功了!真正的魔力 :-) 唯一的问题是,有一种行为我不明白,但在这里解释起来太复杂了。
  • 天啊!我现在真的很喜欢它:-)
【解决方案5】:

截至 2018 年 10 月 2 日,c# 中不可能有一个只读本地,但有一个开放的 proposal 用于该功能,该功能正在进行中 discussion

article 提供了有用的摘要。

【讨论】:

    【解决方案6】:

    在您给出的示例中,您需要将变量声明为static,因为您正在使用方法调用对其进行初始化。如果你用一个常数值初始化,比如 42,你可以使用const。对于类、结构和数组,readonly 应该可以工作。

    【讨论】:

    • 请注意,您不能对变量使用静态,只能对成员使用。
    【解决方案7】:

    const 关键字用于修改一个 字段或本地的声明 变量。

    来自MSDN

    由于 C# 无论如何都不能强制执行“const 正确性”(如 c++),我认为它不是很有用。由于函数的范围非常狭窄,因此很容易不会失去监督。

    【讨论】:

    • 但是我必须指出,eric dahlvang 关于为什么 const 在您的情况下不起作用的问题仍然是正确的。
    • “由于函数的范围非常狭窄,因此很容易不失疏忽。” - 那为什么C++和Java等其他语言也提供这样的机制呢?
    • 不了解 java,但 c++ 也可以在引用上强制执行真正的 const,而 c# 不能。除了在 c++ 中,我从未见过 const 在本地使用过。
    • “由于函数的范围非常狭窄,因此很容易不失控。” — 不正确。尽可能多地使用常量实际上是函数式编程的主要特征。 — “我从未见过 const 在 c++ 中以外的地方使用过” — 当我编写 C++ 时,我一直在使用 const。关于参数、返回值、局部变量。所有可以声明为 const 的东西我都声明为 const。
    • 我不能同意它没有用的说法。事实上,它非常有用。如果我看到一个本地 const 变量,我会立即知道以后不会感到惊讶。它为可读性创造了奇迹。
    猜你喜欢
    • 1970-01-01
    • 2012-03-30
    • 1970-01-01
    • 1970-01-01
    • 2017-12-22
    • 1970-01-01
    • 2012-09-29
    • 1970-01-01
    • 2011-09-29
    相关资源
    最近更新 更多