您实际上可以在 C# 中重现 C++ const 的行为 - 您只需手动完成。
不管Foo是什么,调用者可以修改其状态的唯一方法是调用它的方法或设置属性。
例如,Foo是类型FooClass:
class FooClass
{
public void MutateMyStateYouBadBoy() { ... }
public string Message
{
get { ... }
set { ... }
}
}
因此,在您的情况下,您很高兴他们获得该Message属性,但不对其进行设置,并且您绝对对他们调用该方法不满意。
所以定义一个接口来描述他们可以做什么:
interface IFooConst
{
public string Message
{
get { ... }
}
}
我们省略了 mutating 方法,只保留了属性的 getter。
然后将该接口添加到FooClass.
现在在你的类中Foo,你有一个字段:
private FooClass _foo;
还有一个属性获取器:
public IFooConst Foo
{
get { return _foo; }
}
这基本上可以精确地手动复制 C++const关键字会自动执行的操作。在伪 C++ 术语中,类型的引用const Foo &就像一个自动生成的类型,它只包含那些Foo被标记为成员的const成员。将其转换为 C# 的一些理论上的未来版本,您将声明FooClass如下:
class FooClass
{
public void MutateMyStateYouBadBoy() { ... }
public string Message
{
get const { ... }
set { ... }
}
}
实际上,我所做的只是通过用新关键字标记一个安全成员,将信息合并IFooConst回。所以在某种程度上,添加一个 const 关键字除了对该模式的正式方法之外不会对语言增加太多。FooClassconst
然后,如果你有const一个对象的引用FooClass:
const FooClass f = GetMeAFooClass();
您将只能调用 const 成员f。
请注意,如果FooClass定义是公开的,则调用者可以将 anIFooConst转换为FooClass. 但他们也可以在 C++ 中做到这一点——这被称为“抛弃const”,并涉及一个名为const_cast<T>(const T &).
还有一个问题是接口不是很容易在你的产品版本之间发展。如果第三方可以实现您定义的接口(如果他们可以看到,他们可以自由地做),那么您不能在未来的版本中向它添加新方法,而不需要其他人重新编译他们的代码。但这只是一个问题,如果您正在编写一个可扩展的库供其他人构建。也许内置const功能可以解决这个问题。