为什么 C# 不允许只读局部变量?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/443687/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why does C# disallow readonly local variables?
提问by Brian Genisio
Having a friendly debate with a co-worker about this. We have some thoughts about this, but wondering what the SO crowd thinks about this?
与一位同事就此进行了友好的辩论。我们对此有一些想法,但想知道 SO 人群对此有何看法?
采纳答案by JaredPar
One reason is there is no CLR support for a readonly local. Readonly is translated into the CLR/CLI initonly opcode. This flag can only be applied to fields and has no meaning for a local. In fact, applying it to a local will likely produce unverifiable code.
原因之一是没有对只读本地的 CLR 支持。Readonly 被转换为 CLR/CLI initonly 操作码。此标志只能应用于字段,对本地没有意义。事实上,将其应用于本地可能会产生无法验证的代码。
This doesn't mean that C# couldn't do this. But it would give two different meanings to the same language construct. The version for locals would have no CLR equivalent mapping.
这并不意味着 C# 不能这样做。但它会给同一个语言结构赋予两种不同的含义。本地版本没有 CLR 等效映射。
回答by scottm
I think that's because a function that has a readonly variable may never be called, and there's probably something about it going out of scope, and when would you need to?
我认为这是因为一个具有只读变量的函数可能永远不会被调用,而且它可能会超出范围,什么时候需要?
回答by Jason Punyon
Readonly means the only place the instance variable can be set is in the constructor. When declaring a variable locally it doesn't have an instance (it's just in scope), and it can't be touched by the constructor.
只读意味着实例变量唯一可以设置的地方是在构造函数中。当在本地声明一个变量时,它没有实例(它只是在范围内),并且它不能被构造函数触及。
回答by Jon Skeet
Addressing Jared's answer, it would probably just have to be a compile-time feature - the compiler would prohibit you from writing to the variable after the initial declaration (which would have to include an assignment).
解决 Jared 的回答,它可能只是一个编译时功能 - 编译器会禁止您在初始声明(必须包括赋值)之后写入变量。
Can I see value in this? Potentially - but not a lot, to be honest. If you can't easily tell whether or not a variable is going to be assigned elsewhere in the method, then your method is too long.
我能看到它的价值吗?可能 - 但不是很多,老实说。如果您不能轻易判断是否要在方法的其他地方分配变量,那么您的方法就太长了。
For what it's worth, Java has this feature (using the final
modifier) and I've veryrarely seen it used other than in cases where it hasto be used to allow the variable to be captured by an anonymous inner class - and where it isused, it gives me an impression of clutter rather than useful information.
对于它的价值,Java有此功能(使用final
修改器),我已经非常难得一见它使用比在其情况下,其他有被用来使变量通过一个匿名内部类被捕获-并且它是使用,它给我的印象是混乱而不是有用的信息。
回答by Mike
I was that coworker and it wasn't friendly! (just kidding)
我是那个同事,它不友好!(只是在开玩笑)
I would not eliminate the feature because it's better to write short methods. It's a bit like saying you shouldn't use threads because they're hard. Give me the knife and let me be responsible for not cutting myself.
我不会消除该功能,因为最好编写简短的方法。这有点像说你不应该使用线程,因为它们很难。把刀给我,让我负责不割伤自己。
Personally, I wanted another "var" type keyword like "inv" (invarient) or "rvar" to avoid clutter. I've been studying F# as of late and find the immutable thing appealing.
就个人而言,我想要另一个“var”类型的关键字,如“inv”(不变)或“rvar”,以避免混乱。我最近一直在研究 F#,发现不可变的东西很吸引人。
Never knew Java had this.
从来不知道Java有这个。
回答by andriej
I think it's a poor judgement on part of C# architects. readonly modifier on local variables helps maintain program correctness (just like asserts) and can potentially help the compiler optimize code (at least in the case of other languages). The fact that it's disallowed in C# right now, is another argument that some of the "features" of C# are merely an enforcement of personal coding style of its creators.
我认为部分 C# 架构师的判断很差。局部变量上的 readonly 修饰符有助于保持程序的正确性(就像断言一样),并且可以潜在地帮助编译器优化代码(至少在其他语言的情况下)。现在 C# 中不允许使用它的事实是另一个论点,即 C# 的某些“功能”仅仅是其创建者个人编码风格的强制执行。
回答by brgerner
I would like local readonlyvariables in the same manner as I like local constvariables. But it has less priority than other topics.
Maybe its priorityis the same reason for C# designers to not (yet!)implement this feature. But it should be easy (and backward compatible) to support local readonly variables in future versions.
我想要局部只读变量,就像我喜欢局部常量变量一样。但它的优先级低于其他主题。
也许它的优先级与 C# 设计人员不(还!)实现此功能的原因相同。但是在未来的版本中支持本地只读变量应该很容易(并且向后兼容)。
回答by Mike de Klerk
I know, this doesn't answer the why to your question. Anyway, those reading this question might appreciate the code below nonetheless.
我知道,这不能回答你的问题的原因。无论如何,阅读这个问题的人可能会欣赏下面的代码。
If you are really concerned with shooting your self in the foot when overriding a local variable that should only be set once, and you don't want to make it a more globally accessible variable, you could do something like this.
如果在覆盖一个只应设置一次的局部变量时,您真的很担心自己在脚下射击,并且您不想使其成为更全局可访问的变量,则可以执行以下操作。
public class ReadOnly<T>
{
public T Value { get; private set; }
public ReadOnly(T pValue)
{
Value = pValue;
}
public static bool operator ==(ReadOnly<T> pReadOnlyT, T pT)
{
if (object.ReferenceEquals(pReadOnlyT, null))
{
return object.ReferenceEquals(pT, null);
}
return (pReadOnlyT.Value.Equals(pT));
}
public static bool operator !=(ReadOnly<T> pReadOnlyT, T pT)
{
return !(pReadOnlyT == pT);
}
}
Example usage:
用法示例:
var rInt = new ReadOnly<int>(5);
if (rInt == 5)
{
//Int is 5 indeed
}
var copyValueOfInt = rInt.Value;
//rInt.Value = 6; //Doesn't compile, setter is private
Maybe not as less code as rvar rInt = 5
but it works.
也许没有那么少的代码,rvar rInt = 5
但它有效。
回答by Colonel Panic
You can declare readonly local variables in C#, if you're using the C# interactive compiler csi
:
如果您使用的是 C# 交互式编译器,则可以在 C# 中声明只读局部变量csi
:
>"C:\Program Files (x86)\MSBuild.0\Bin\csi.exe"
Microsoft (R) Visual C# Interactive Compiler version 1.3.1.60616
Copyright (C) Microsoft Corporation. All rights reserved.
Type "#help" for more information.
> readonly var message = "hello";
> message = "goodbye";
(1,1): error CS0191: A readonly field cannot be assigned to (except in a constructor or a variable initializer)
You can also declare readonly local variables in the .csx
script format.
您还可以在.csx
脚本格式中声明只读局部变量。
回答by Derek Liang
It is an oversight for c# language designer. F# has val keyword and it is based on CLR. There is no reason C# can't have the same language feature.
这是 c# 语言设计者的疏忽。F# 有 val 关键字,它基于 CLR。C# 没有理由不能具有相同的语言功能。