Just as C# 2 introduced T?
as a short-hand for Nullable<T>
, shouldn't C# consider introducing a short-hand for even the more popular IEnumerable<T>
? Like T*
?
Wouldn't this help make something that should be simple to read, like
Func<IEnumerable<string>, IEnumerable<string>> f;
in fact simple to read?
Func<string*, string*> f;
What would be the downside, if any? Naturally, T*
introduces some syntactic overlap with
pointers in C#
[1] but then what would be an alternative? T+
?
Bear in mind:
/unsafe
[2] switch and even then in methods explicitly marked with
unsafe
[3].IEnumerable<int*>
today to mean a sequence of integer pointers. The compilation will fail with
CS0306
[4].Rationale:
With the introduction of LINQ, the
IEnumerable<T>
[5] has taken a center stage as the most generic way to represent a collection or sequence. The generic syntax, however, when used within delegates or method signatures can make code long and unreadable. For example, here is a simple use of
Func<T, R>
[6] to declare a function variable that accepts and returns a sequence of strings:
Func<IEnumerable<string>, IEnumerable<string>> f;
This is a simple case and already makes the code unnecessarily long to write and read back. So, just as C# 2 introduced T?
as a shorthand for Nullable<T>
, should C# consider introducing a shorthand for IEnumerable<T>
, like T*
?
Yeah, would be nice.
It's hard to find a character that doesn't look ugly inside the angle brackets. Maybe the hash sign:
Func<string#, string#> f;
Very visible, easy to type, only used by precompiler and stands for a number of items. The best: C# !
IEnumerable<T>
does not necessarily represent a finite sequence, which is implied by #
meaning number of items. #
is really only applicable to things with a .Count
or .Length
property, like lists and arrays. - Bryan Watts
Obviously C# can't do this now, but if I were starting C# from scratch, I'd be tempted to make T[]
the shorthand for IEnumerable<T>
.
I'll vote yes.
I'm not normally in favour of any such ASCII junk. However, IEnumerable
is arguably the most fundamental type of the .NET framework since at least .NET 3.5. It is clearly much more imporant than native pointers (why have a syntax for unsafe pointers?!) or Nullable
types.
I think characters are reasonable for these and like how f# does it which is to call them Sequences and have seq<T>
.
That said in most cases I rarely write IEnumerable<T>
any where except at method definitions (where the extra verbosity is not a significant concern).
In most cases IEnumerables are either implicit (via fluent style chained method calls) or are assigned to a variable defined by var like so:
int[] list = {-2,-1,0,1,2,3,4,5,6,7,8,9 };
double d = list.Where(x => x > 0)
.Select(x => Math.Sqrt(x))
.Where(x => x < 5)
.Max();
var evens = list.Where(x => x % 2 == 0);
If I change the type of list (say to an long the evens will cascade nicely)
I would strongly disagree with using * since the potential confusion with pointers is high. I also dislike +, and I'm pretty sure using it in that way would seriously complicate the parsing logic. In terms of widely available punctuation (on most keyboards) available for use you have $, ¬ and postfixed '@'.
Really only $ is available but since that is the sole remaining character that could be used to extend the language I don't believe that shortening IEnumerable<T>
justifies its use.
Assuming you ever wanted to add regex support as a language intrinsic then the $ would be an obvious choice for prefixing the resultant automatic variables. I believe that usage would trump this one. I am by no means certain that regexes should be a language intrinsic but would suggest them as a reasonable suggestion for why addition of syntax is a very careful weighing of priorities.
Why not just do it as in Haskell?
[string]
Examples:
Func<[string], [string]> f;
static [U] Map<T, U>(this [T] input, Func<T, U> mapper)
static [T] Flatten<T>(this [[T]] input)
There's a potential conflict with attributes, but the context would disambiguate it.
void Method([AnAttribute] [string] myStrings);
Also, an array of enumerables (or an enumerable of arrays) would be a little awkward (but it's a rare construct anyway):
[string][] myArrayOfStrings;
[string[]] myArraysOfStrings;
The syntax can also be used for enumerable literals:
[string] theBugs = ["John", "Paul", "George", "Ringo", "Y2K"];
[1] http://en.wikipedia.org/wiki/Apple_II_seriesHave you tried following?
using IES = System.Collections.Generic.IEnumerable<string>;
Does this serve purpose?
Edit: This would be still little more work then suffix way.
I'm undecided on the need for syntactic sugar, Resharper has gone a long way to reducing RSI for me.
For syntax I would suggest T~ e.g. string~
tilde is already an operator, but so are most of the other suggestions, and it is used pretty infrequently in most code.
C# should adopt the F# seq<T
> alias. Why have a six-syllable word for a two-syllable concept?
I wholeheartedly support the idea of shorthand for IEnumerable, but I'd be hesitating to use the asterisk just for the sake of preventing confusion for developers in other languages where the asterisk denotes a pointer.
What about T# or T!?
T!
should actually be used to denote a non-nullable reference type T. Pretty much the opposite of T?
. - Jordão
Well, maybe it's a good idea but you can't use an asterisk - C# already supports pointers using the asterisk. e.g. (You need to use the /unsafe compiler flag to get this to compile)
using System;
namespace ConsoleApplication7
internal class Program
{
public static unsafe void Main()
{
var i = 5;
// unsafe method: uses address-of operator (&)
Add12ToTheInt(&i);
Console.WriteLine(i);
}
private static unsafe void Add12ToTheInt(int* p)
{
*p += 12;
}
}
}
I'll vote no.
I believe adding an alias for IEnumerable at this point would create confusion.
If you want to save some typing either:
1) Create a snippet, or
2) If you use ReSharper, assign the expression to a var then jump to beginning of line and use the ReSharper context menu to change to explicit type. Using Visual Studio shortcuts it would be HOME, ALT+ENTER, ENTER.
I like the idea.
Considering how IEnumerable is so pivotal to 3.5 as everyone is saying, why not borrow from the name of C# as it is? In other words, use
Func<string#, string#> f;
The #
looks likes an array type-of-thing, which alludes to IEnumerable<T>
.
Sure, you might have a little issue with #define
's, but since it would come after a type, it should be relatively easy to parse without being ambiguous.
I'd vote yes, too. I'm quite sure I'd love this more than the Nullable-notation. :)
Personally I like the star, because it's a sign that is well-known for multiplicities in some model syntax definitions, e.g. conceptional DB models. But I do understand that it's bad for developers familiar with the "C-style pointer syntax".
By the way, is there already kind of official post to the C# language designers, or even some kind of discussion?
Just to throw my own completely ridiculous suggestion out there: what about T...
?
Then you could write:
Func<string..., string...> f;
More typing than the single character suggestions, obviously -- but I think that both *
and +
are problematic, for reasons already expressed (overlap with existing syntax).
#
and !
on the other hand just seem kind of arbitrary. There's not really any logical connection between #
or !
and the concept of a sequence (is there?). Plus: did you know
the sharp symbol (♯)
[1] is not the same as
the number sign (#)
[2]?
With ...
, the implication of potentially multiple items is clear (to me, anyway). And I could be wrong, but I don't think there's any other context in which consecutive dots would compile; so I'm not seeing any syntactical overlap.
UPDATE: OK, I think the T{}
suggestion is much better, actually.
Func<string.., string..> f;
, T.. enumeration;
. I think there is a programming language where it is like that (Delphi?). The {}
I don't like so much actually. - herzmeister
I like the idea but I think the syntax should have some relationship with array notation. Maybe string<>
or string[?]
?
Update
Considering that <> is already used and [?] is hard to type (though not as tough as IEnumerable<>), what about:
string[[]]
I'm sure there are many other variations, but the goal would be to come up with something that is intuitive to read and I don't think that string*
or similar says "collection", hence dwelling on the array syntax.
Of course you could always alias the IEnumerable<T>
via using
statements without requiring any changes to the language and create declarations like Func<Strings, Strings>
.
I've never thought of that but it sure makes sense in when you put it in context. I have however started abusing var for the reason of having to type less.
I'd vote no. How often do you find yourself typing this? Use var more often, or let ReSharper or Visual Studio do the typing for you.
{}
and yet now reading that idea makes it seem like such an obviously good choice. - Dan TaoIQueryable<>
then? - comecme