我目前知道有两种方法可以在C#中使实例不可变:
void Foo()
{
// Will be serialized as metadata and inserted
// as a literal. Only valid for compile-time constants
const int bar = 100;
}
class Baz
{
private readonly string frob;
public Baz()
{
// Can be set once in the constructor
// Only valid on members, not local variables
frob = "frob";
}
}
保证一些实例一旦实例化就不会被改变,这将是一件好事。 const
和readonly
在很小程度上做到这一点,但范围有限。我只能使用const
作为编译时常量,readonly
作为成员变量。
有没有办法在初始实例化之后给出局部变量不变性(readonly
的工作方式,但在更一般的层面上)?
<子>
Scala使用var
关键字执行此操作,该关键字声明了一个新的不可变值,在获取其初始值后无法重新分配:
var xs = List(1,2,3,4,5) // xs is a value - cannot be reassigned to
xs = List(1,2,3,4,5,6); // will not compile
答案 0 :(得分:5)
除了字段之外,您无法阻止在C#中重新分配变量,正如您已经提到的那样使用const
或readonly
。
您可以通过包装它来创建任何现有可变类型的自己的不可变版本,或者如果它是您自己的类,重新编写它是不可变的但是您无法在方法中实现变量,这是您的问题似乎到了。
F#有一些不可变性的选项(如果我没记错的话,是'let
关键字)C#没有,所以如果你还想利用.NET的强大功能,可能值得一看F#但具有完全不变性。
答案 1 :(得分:1)
如果包装器是静态的,则无法覆盖。这样就会对变量名称和类型安全性进行编译时编译。
public static class ReadOnly
{
private static readonly Dictionary<string, object> values = new Dictionary<string, object>();
public static bool SetValue(string name, object data)
{
if (values.ContainsKey(name))
return false;
values[name] = data;
return true;
}
public static object GetValue(string name)
{
return values[name];
}
}
ReadOnly.SetValue("xs", 1);
ReadOnly.SetValue("xs", 1); // will crash