在C ++中,你会看到void func(const T& t)
无处不在。但是,我在.NET中没有看到类似的东西。为什么?
我注意到使用struct的参数很多。但是我看不到readonly / const的函数。事实上,现在我尝试了它,我不能使用这些关键字来制作一个承诺不修改传入的列表的函数。有没有办法让调用者承诺这个函数永远不会修改列表的内容?有没有办法说调用代码并说这个列表永远不应该被修改?(我知道我可以克隆列表或查看文档,但我喜欢编译错误)
发布于 2019-05-20 10:39:23
不变性仍然是C#成熟的领域。到目前为止,C#还没有采用const
C ++ 的语义......我认为这是一件好事。const
C ++中的行为经常使设计类层次结构变得具有挑战性,这些层次结构以您想要的方式工作。在不合需要的情况下,看到代码const_cast<>
可以绕过constness,这种情况并不少见。希望C#的设计者能够发明一种更简单但仍然富有表现力的选择。
目前,没有语言功能将传递给方法的参数或对象标记为不可变。您可以做的最好的事情是使用仅允许读取操作的接口(或更好的包装器)传递对象。
对于.NET中的某些标准集合,您可以使用ReadOnlyCollection
包装器,它ICollection
在只读容器中封装任何可变类型。
创建不可变类型需要规划和了解语言功能。例如,readonly
关键字是您的朋友。它允许您将类或结构的成员声明为不可变的。不幸的是,这种不变性仅适用于引用,而不适用于引用对象的成员。这意味着您可以声明:
private readonly int[] m_Values = new int[100];
public void SomeMethod()
{
m_Values = new int[50]; // illegal, won't compile!
m_Values[10] = 42; // perfectly legal, yet undesirable
}
在上面的示例中,对数组的引用是不可变的,但数组的各个元素不是。当然,这种行为超出了数组。
我在设计不可变类型时发现有用的做法是将不可变行为分离到自己的接口,然后由管理数据的类实现。该接口仅公开get属性和方法,保证不会改变对象的状态。然后,可以将类型的实例作为该接口类型的参数传递给方法。这是一种弱不变性支持形式 - 因为被调用的方法通常可以将引用转换为可变类型。一个更好但更麻烦的替代方法是创建一个包装器实现,它实现相同的接口并维护对实际实例的引用(很像ReadOnlyCollection
)。这是更多的工作,但为不变性提供了更强有力的保障。
您选择使用的方法取决于保证不变性的重要性,以及您愿意花多少时间和精力来实现目标。
发布于 2019-05-20 11:11:56
const
C#中的方法参数没有修饰符。如果你想拥有类似于const保证的东西,你可以在接口中使用不可变类型。例如,方法可以接受IEnumerable<T>
而不是可变集合类型。你也可以看看ReadOnlyCollection
。
https://stackoverflow.com/questions/-100001156
复制相似问题