我是C#世界的新手,我找不到在C#中声明只读变量的方法(类似于在c ++中声明“const”变量)。有吗?
我会举个例子:
...
int f() { return x; } // x is not const member
...
void g() {
int readOnlyVar = f(); // is there a method to declare readOnlyVar as read only or const
// Some code in which I want to restrict access to readOnlyVar to read only
}
答案 0 :(得分:11)
没有相同的类比。
readonly
关键字允许变量值变异,但仅限于构造函数。
const
关键字表示该值不能变异,需要是编译时常量,并且只能是以下类型之一:sbyte,byte,short,ushort,int,uint,long,ulong,char ,float,double,decimal,bool,string,enum-type或reference-type。 (C#4.0规范§10.4)。
在c#中,readonly
仅适用于字段,不能应用于局部变量。
答案 1 :(得分:4)
不,您的代码示例没有解决方案。
C#中的 const
用于编译时常量,并且由于您的变量从函数中获取其值,因此在编译时不知道。
readonly
关键字可以满足您的需求,但这只适用于类中的成员变量(并且只允许在类的构造函数中设置变量)。
但是,另一方面,你为什么需要呢?如果你的函数很长,它应该被重构成更小的函数。如果它不是很长,那你为什么要强制执行这样的规则呢?只是不指定给readOnlyVar
可能是我最好的建议,我害怕。
答案 2 :(得分:2)
有两种方法可以将变量设置为只读。
public class ClassA
{
private const int I = 5;
private readonly int J = 5;
}
const关键字将在编译时设置值。 readonly关键字将在构造时设置值。因此,如果每个实例需要不同的值,请使用readonly。否则使用const。
答案 3 :(得分:1)
在c#中我们使用const或readonly关键字来声明一个常量。
<强>常量强>
常量成员在编译时定义,不能在运行时更改。常量使用const关键字声明为字段,必须在声明时初始化。例如;
public class MyClass
{
public const double PI = 3.14159;
}
在代码中的任何其他地方都无法更改PI,因为这会导致编译器错误。
<强>只读强>
只读成员就像一个常量,因为它代表了一个不变的值。不同之处在于readonly成员可以在运行时,构造函数中初始化,也可以在声明它们时进行初始化。例如:
public class MyClass
{
public readonly double PI = 3.14159;
}
或
public class MyClass
{
public readonly double PI;
public MyClass()
{
PI = 3.14159;
}
}
因为readonly字段可以在声明或构造函数中初始化,所以readonly字段可以具有不同的值,具体取决于所使用的构造函数。 readonly字段也可用于运行时常量,如以下示例所示:
public static readonly uint l1 = (uint)DateTime.Now.Ticks;
备注强>
readonly成员不是隐式静态的,因此如果需要,static关键字可以显式地应用于readonly字段。
readonly成员可以在初始化时使用new关键字来保存复杂对象。 readonly成员不能举行枚举。
信誉来到这里: http://www.dotnetspider.com/forum/69474-what-final-c-i-need-detailed-nfo.aspx
答案 4 :(得分:0)
这不是语言功能,而是you’re not the only person interested in such a feature。不过,你确实有一些选择。您可以使用具有readonly
成员变量的类替换方法的实现。但这是一个巨大的痛苦,并且真正爆炸了代码的大小。 (当你编写lambdas或使用async
方法时,C#会做类似于将locals提升到类字段并将lambda或async方法转换为自动生成类的方法。我们基本上做同样的事情,但是手动使得我们可以设置readonly
。)
class Scope
{
int x;
int f() => x; // x is not const member
void g()
{
new gImpl(f()).Run();
}
class gImpl
{
readonly int readOnlyVar;
public gImpl(
int readOnlyVar)
{
this.readOnlyVar = readOnlyVar;
}
public void Run()
{
// Some code in which I want to restrict access to readOnlyVar to read only
// error CS0191: A readonly field cannot be assigned to (except in a constructor or a variable initializer)
readOnlyVar = 3;
}
}
}
另一种需要较少代码但仍然笨拙的替代方法是滥用foreach
的功能。 foreach
关键字不允许您分配给迭代变量。所以你可以这样做:
class Scope
{
int x;
int f() => x;
void g()
{
foreach (var readOnlyVar in new[] { f(), })
{
// Some code in which I want to restrict access to readOnlyVar to read only
// error CS1656: Cannot assign to 'readOnlyVar' because it is a 'foreach iteration variable'
readOnlyVar = 3;
}
}
}
foreach
方法可以更容易地使用匿名类型,但您可以使用泛型与类型推断相结合来使用类方法的匿名类型。