Replies: 6 comments
-
From @AdamSpeight2008 on February 5, 2015 15:30 I think a trait (#129) would work as a better restriction. trait {
requires: Add (T)-> void
ensure: _Count.Old < _Count.New;
} |
Beta Was this translation helpful? Give feedback.
-
I hate to betray my own use case, but it was indeed using collection initializers on types that were not morally collections when I ran into this restriction. I wanted a lightweight, whitespace flexible syntax for passing a number of delegates to an initializer. The delegates were used internally to build up somthing along the lines of a pattern matching expression and there was nothing conceptually collection like about the container object at all and, as I really didn't want to use new on it either, I'm in favor of Jon Skeet's suggestions. Irregardless, while I would like to see this on factories/builders, I really just want the match expression (with recursive patterns) back ❤️ |
Beta Was this translation helpful? Give feedback.
-
Hi @gafter -
Some add methods return void, some return an index, and some return the actual item added. All should be valid for the Add trait.
In the class above, adding (6,10) to the set could result in ValidRanges reducing down to only having one element: (1, 15). |
Beta Was this translation helpful? Give feedback.
-
@TonyValenti Firstly it wasn't @gafter who proposed the The requirement |
Beta Was this translation helpful? Give feedback.
-
I would like this. Tagging @jcouv for visibility. Here's an example of a real API today where this is unpleasant: public override int GetHashCode()
{
var hash = new System.HashCode();
hash.Add(a);
hash.Add(b);
hash.Add(c);
hash.Add(d);
hash.Add(e);
hash.Add(f);
hash.Add(g);
hash.Add(h);
hash.Add(i);
return hash.ToHashCode();
} It's necessary to write things this way instead of something more simple like: public override int GetHashCode()
=> new HashCode() { a, b, c, d, e, f, g, h, i }.TohashCode(); This is because it's reasonable to have "construction" APIs that use As an aside, i hit this while designing a Pulumi API where we want users to be able to easily construct something using Thoughts? |
Beta Was this translation helpful? Give feedback.
-
Allowing to use extension methods with duck typing (that happens in collection initializers, foreach and await) would solve the issue as well. public static IEnumerator GetEnumerator(this HashCode _) => throw new NotImplementedException(); |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
From @SolalPirelli on February 5, 2015 14:40
C# specification §7.6.10.3, Collection initializers:
This restriction is explained in an old blog post by Mads Torgersen: it ensures that collection initializers cannot be used on types whose
Add
method does not add an element to a collection, but does things like computing a sum.However, as discussed in a CodePlex issue, there are a few use cases where the collection initializer syntax is desirable on objects that can't/shouldn't implement
IEnumerable
.Additionally, collection initializers can already be used on immutable collections if they provide a constructor, since they're likely to both implement
IEnumerable
and have anAdd
method, but this obviously doesn't work properly.Therefore, I suggest one of the following:
Add
method.The simplest option. I do not have evidence for this, but I very much doubt that people actually try to use collection initializers on types that are not thought of as collections.
The safest option, ensuring that types won't get collection initializers if they don't want them.
The most complex option, which would probably fit more in a general "make C# more friendly to DSLs" feature.
Another idea (which is orthogonal to these suggestions) is to add an attribute that disables collection initializers, even on types implementing
IEnumerable
.Copied from original issue: dotnet/roslyn#266
Beta Was this translation helpful? Give feedback.
All reactions