Cha*_*ion 2 c# operator-overloading immutability
它当然不会脱离.NET框架的标准实践.当我看到一个时,a + b
我总是假设会创造一些新东西.
static void Main(string[] args)
{
var list = BuildList(ImmutableList<int>.Empty);
var sum = (list + 500).Sum();
Console.WriteLine(sum);
Console.ReadLine();
}
static ImmutableList<int> BuildList(ImmutableList<int> list)
{
if (list.Count < 1000)
{
return BuildList(list + list.Count);
}
return list;
}
Run Code Online (Sandbox Code Playgroud)
更新
请参阅Jon Skeet关于如何在不可变列表上命名方法的帖子.
令人惊讶的回应
我很惊讶地看到这么多答案都认为这是有道理的.原则上我也同意,但是对于我来说,阅读冗长的代码比阅读简洁,代码简洁的人更容易.从我的工作经验来看,他们似乎占多数.
我个人不建议重载运算符,比如+
任何不打算被视为基元的类.特别是,在我看来,收藏品永远不应超载运营商.
当你有一个小的不可变类或结构,意味着表现得像一个"原始"类型时,运算符重载是有意义的.但是,当您开始尝试为其他类执行此操作时,它确实会影响可维护性.
我推荐使用显式方法调用.
阅读完评论后,我的建议是使用Concat()
(以匹配框架中的Enumerable.Concat).我更喜欢的另一个选择是Construct()
,ala cons(虽然缺点通常是pre),使用非常清楚:
var list = BuildList(ImmutableList<int>.Empty);
var list2 = list.Concat(500);
// Or: var list2 = list.Construct(500);
Run Code Online (Sandbox Code Playgroud)
重载的不可变字符列表是+
有意义的; 我们称它们为弦乐.相比之下,你可以说,重载+
操作符以调用Concat
操作的任何事物的不可变列表都是有意义的.
顺便说一下,我最近创建了一个类似于你所描述的功能:
public static IEnumerable<T> Append<T>(this IEnumerable<T> list, T item)
{
foreach (T i in list)
yield return i;
yield return item;
}
Run Code Online (Sandbox Code Playgroud)
我决定Append
在列表中添加一个元素,同时Concat
在列表末尾添加一个完整列表.