您实际上可以在 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 关键字除了对该模式的正式方法之外不会对语言增加太多。FooClass
const
然后,如果你有const
一个对象的引用FooClass
:
const FooClass f = GetMeAFooClass();
您将只能调用 const 成员f
。
请注意,如果FooClass
定义是公开的,则调用者可以将 anIFooConst
转换为FooClass
. 但他们也可以在 C++ 中做到这一点——这被称为“抛弃const
”,并涉及一个名为const_cast<T>(const T &)
.
还有一个问题是接口不是很容易在你的产品版本之间发展。如果第三方可以实现您定义的接口(如果他们可以看到,他们可以自由地做),那么您不能在未来的版本中向它添加新方法,而不需要其他人重新编译他们的代码。但这只是一个问题,如果您正在编写一个可扩展的库供其他人构建。也许内置const
功能可以解决这个问题。