Roslyn: Proposal: AddRange sugar for collection initializers

Created on 21 Jan 2017  路  6Comments  路  Source: dotnet/roslyn

var list = new List<int> {
  GetValue(), 
  yield GetValues(),
};

->

var list = new List<int>();
list.Add(GetValue());
list.AddRange(GetValues());

Most helpful comment

Not sure this is really needed. All you need is a simple extension method:
cs public static List<T> Add<T>(this List<T> list, IEnumerable<T> addition) { list.AddRange(addition); return list; }

And then it becomes possible to do the following:
cs var list = new List<int> { GetValue(), GetValues() };

All 6 comments

@alrz Is yield really required? or it's optional?

I mean I can pass both _versions_ to AddRange(...) so I wonder if this is the case here too? in short what's the point of yield?

public IEnumerable<int> GetValues1()
{
    return new[] {1, 2};
}

public IEnumerable<int> GetValues2()
{
    foreach (var item in GetValues1())
    {
        yield return item;
    }
}

@eyalsk I think the yield here has nothing to do with yield return, it's just syntax that tells the compiler to call AddRange(), not Add(). (And the compiler can't do that itself, at least not always. Consider new List<object> { yield new object[0] }, which would change meaning if you remove yield.)

@alrz I like the idea and I understand why new syntax is needed, but I don't like yield much, since I think it doesn't make much sense and would cause confusion.

Also, it would be ambiguous: new List<int> { yield(GetValues()) } is already valid syntax. This issue can be solved by using two-word keywords (like yield return) or by adding a method modifier (like async), but neither seems like a good fit to me here.

Not sure what would be a good alternative syntax.

Perhaps

var list = new List<int> {
  GetValue(), 
  [GetValues()]
};

->

var list = new List<int>();
list.Add(GetValue());
list.AddRange(GetValues());

It would be short and unambiguous as an opening square bracket '[' as the first character/token in a initialization expression is nowadays invalid, AFAIR.

Not sure this is really needed. All you need is a simple extension method:
cs public static List<T> Add<T>(this List<T> list, IEnumerable<T> addition) { list.AddRange(addition); return list; }

And then it becomes possible to do the following:
cs var list = new List<int> { GetValue(), GetValues() };

@svick Thanks for the enlightenment. 馃槈

@DavidArno Thanks, that's just what I need!

As @svick mentioned, the yield keyword is ambigious and since collection initializers are convention-based, this would be a non-issue.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

MadsTorgersen picture MadsTorgersen  路  3Comments

joshua-mng picture joshua-mng  路  3Comments

marler8997 picture marler8997  路  3Comments

ashmind picture ashmind  路  3Comments

asvishnyakov picture asvishnyakov  路  3Comments