Does an immutable list that overloads '+' makes sense?

微笑、不失礼 提交于 2019-12-10 23:19:51

问题


It certainly does not break from the standard practice of the .NET framework. When I see a a + b I always assume something new will be created.

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;
}

Update

See Jon Skeet's post on what to name methods on immutable lists.

Surprising Responses

I am quite surprised to see so many answers that concur that this makes sense. In principle I also agree but it is way easier for me to read verbose code than it is for someone who is uncomfortable with terseness to read, well terse code. From my working experience they seem to be the majority.


回答1:


I personally would not recommend overloading operators like + for any class that isn't meant to be treated as a primitive. In particular, collections, in my opinion, should never overload operators.

Operator overloading makes sense when you have a small immutable class or struct that is meant to behave like a "primitive" type. However, when you start trying to do this for other classes, it really impacts maintainability.

I'd recommend making explicit method calls, instead.


After reading the comments, my recommendation would be to use Concat() (to match Enumerable.Concat in the Framework). Another option I would prefer would be Construct(), ala cons (though cons typically prepends), to make the usage very clear:

var list = BuildList(ImmutableList<int>.Empty);
var list2 = list.Concat(500); 
// Or: var list2 = list.Construct(500);



回答2:


An immutable list of characters that overloads + makes sense; we call them strings. You could, by analogy, say that an immutable list of anything that overloads the + operator to invoke the Concat operation makes sense.

BTW, I recently created a similar function to what you're describing:

public static IEnumerable<T> Append<T>(this IEnumerable<T> list, T item)
{
    foreach (T i in list)
        yield return i;
    yield return item;
}

I decided that Append adds a single element to the list, while Concat adds a whole list to the end of the list.




回答3:


What does + mean in this context? It seems really unclear to me (without reading code). IList + IList I could see as maybe a union operator or combining the lists (keeping duplicates) or any number of other things. IList + int just confuses me. It seems to me a method with a clear name will make for much more readable code than an operator somebody will have to look up, or comments every time you use the overloaded operator.




回答4:


One thing about operators, is that people expect them to be relatively efficient. There's nothing to say that this should hold, but people do seem to expect it.

If internally, the structure of such a list allowed you to create a concatenated list by having it store references to the two it was sourced from (quite possible, especially considering that immutability negates the risk of confusing side-effects), then I'd go for it. If it was potentially to have to do a relatively expensive operation, then I wouldn't. "concatenate()" might make someone consider "do I really need to move this much memory around here in this tight loop I'm currently in, or should I consider a different approach" at a time when such a thought is appropriate.




回答5:


I'd do it.

After all, a string is a list of characters.

And yes, if I saw <list> + <list> I'd immediately think concatenate (the only other possibility is vector sum and that's rare).



来源:https://stackoverflow.com/questions/3428667/does-an-immutable-list-that-overloads-makes-sense

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!