const 正确性的重点是能够提供用户无法更改或删除的实例视图。编译器通过指出何时从 const 函数中破坏 const 或尝试使用 const 对象的非 const 函数来支持这一点。因此,在不复制 const 方法的情况下,有没有可以在 C# 中使用的具有相同目的的方法?
我知道不变性,但这并没有真正延续到容器对象的名称中,只是一个例子。
const 正确性的重点是能够提供用户无法更改或删除的实例视图。编译器通过指出何时从 const 函数中破坏 const 或尝试使用 const 对象的非 const 函数来支持这一点。因此,在不复制 const 方法的情况下,有没有可以在 C# 中使用的具有相同目的的方法?
我知道不变性,但这并没有真正延续到容器对象的名称中,只是一个例子。
我也遇到过很多次这个问题,最终使用了接口。
我认为放弃 C# 是任何形式,甚至是 C++ 的演变的想法很重要。它们是两种不同的语言,具有几乎相同的语法。
我通常通过定义一个类的只读视图来表达 C# 中的“常量正确性”:
public interface IReadOnlyCustomer
{
String Name { get; }
int Age { get; }
}
public class Customer : IReadOnlyCustomer
{
private string m_name;
private int m_age;
public string Name
{
get { return m_name; }
set { m_name = value; }
}
public int Age
{
get { return m_age; }
set { m_age = value; }
}
}
为了获得 const-craziness(或函数式编程术语中的纯粹性)的好处,您需要以一种不可变的方式设计您的类,就像 c# 的 String 类一样。
这种方法比仅仅将对象标记为只读要好得多,因为使用不可变类,您可以在多任务环境中轻松传递数据。
我只是想提醒您,许多 System.Collections.Generics 容器都有一个 AsReadOnly 方法,该方法将为您返回一个不可变的集合。
接口就是答案,实际上比 C++ 中的“const”更强大。const 是针对“const”被定义为“不设置成员或调用设置成员的东西”的问题的一刀切解决方案。在许多情况下,这是 const-ness 的一个很好的简写,但不是所有情况。例如,考虑一个基于某些成员计算值但也缓存结果的函数。在 C++ 中,这被认为是非常量,尽管从用户的角度来看,它本质上是 const。
接口使您可以更灵活地定义要从类中提供的特定功能子集。想要常量吗?只需提供一个没有变异方法的接口。想要允许设置一些东西而不是其他东西?提供一个只包含这些方法的接口。
同意其他人的观点,即使用您在构造函数中初始化的只读字段来创建不可变对象。
public class Customer
{
private readonly string m_name;
private readonly int m_age;
public Customer(string name, int age)
{
m_name = name;
m_age = age;
}
public string Name
{
get { return m_name; }
}
public int Age
{
get { return m_age; }
}
}
或者,您还可以在属性上添加访问范围,即公共获取和保护集?
public class Customer
{
private string m_name;
private int m_age;
protected Customer()
{}
public Customer(string name, int age)
{
m_name = name;
m_age = age;
}
public string Name
{
get { return m_name; }
protected set { m_name = value; }
}
public int Age
{
get { return m_age; }
protected set { m_age = value; }
}
}
readonly的问题在于它只允许引用(指针)保持不变。引用(指向)的事物仍然可以修改。这是棘手的部分,但没有办法绕过它。实现常量对象意味着使它们不公开任何可变方法或属性,但这很尴尬。
另请参阅有效的 C#:50 种改进 C# 的特定方法(第 2 项 - 首选只读而不是 const。)