Why only Seven elements in a Tuple in C# 4.0, with the eighth being another tuple?
In F# the syntax sugar hides开发者_如何学C the CLR implementation, why not in C# 4.0?
UPDATE: This answer was written over a decade ago. A syntax for tuples was added to C# 7.0.
We considered adding a syntactic sugar for tuples. I think everyone agrees that it's a nice feature, but it simply didn't fit into the budget.
It seems unlikely that someone using the features of the C# language to their appropriate level would require a Tuple containing more than 7 elements, especially given the existing and established techniques for problem solving and C#'s primarily OO approach to solution development.
F#, on the other hand, is a language designed to be primarily functional. As such, it does things in a primarily functional way and the language features are focused toward that primary concept. Resultantly, it made a lot more sense to spend the resources required to supply the language feature you're requesting in F# than it did in C#.
Remember that all new language features start with 100 points against them. :)
The following is a good MSDN article by Matt Ellis on the Base Class Libraries (BCL) team that goes through exactly what they were thinking on this and some other key issues regarding the Tuple
classes.
Building Tuple: http://msdn.microsoft.com/en-us/magazine/dd942829.aspx
Due to the design of .NET generics, the number of generic type parameters is fixed at compile time. Therefore, they had to pick some number of generic parameters to do the implementation. The article explains that it is patterned on the existing Action
and Func
delegates. Ironically, additional delegates for Action
and Func
were subsequently added taking the number of generic type parameters up to 16, but the Tuple
developers did not follow suit.
This is speculation on my part, but I suspect that another factor is that F# has a rather elaborate mechanism for storing language specific metadata. There needs to be some way to distinguish between a "7-tuple the last element of which is a 3-tuple" and a 9-tuple, even though they are encoded in the same way in terms of .NET types. F# accomplishes this via custom metadata blobs, just as it uses metadata to store constraints which are more expressive than those which are built in to .NET (e.g. enum or member constraints). C# doesn't have a history of storing elaborate, language-specific metadata with assemblies, some form of which would be a necessary prerequisite for handling extended tuples (although a custom attribute might suffice in this case).
Well, the simple answer to your question is that C# doesn't provide any syntactic sugar for working with tuples, so there is no way it could hide nesting of tuples when there are more than 8 elements.
Of course, I guess you're actually asking why there is no syntactic sugar for working with tuples in C# 4.0. I think the main reason why it isn't there is that it encourages lightweight style of programming which isn't usually supported in C# (but works very well for F# programmers).
In F#, it is perfectly fine to write code that looks like this:
let parseRecord rc = // some code to parse the argument let (left, top, wid, hgt, str) = parseRecord record
However, this code is reasonable only in the early phase of the development pocess (when writing some prototype and experimenting) or if the functionality is very localized (used within one function). In a more evolved version of the code, you would probably replace this with some more suitable data structure (e.g. F# record) to make the code more readable and I think this is what people typically do in F#
On the other hand, if C# propgrammer wrote something like the following code, people would be quite scared how unreadable the code is:
{ int, int, int, int, string } ParseRecord(string record) { // some code to parse the argument } var (left, top, wid, hgt, str) = ParseRecord(record);
So, I think the overall style of programming in C# is simply less suitable for lightweight features as tuples and pattern matching on tuples, because it doesn't work that well with the rest of the language.
Of course, there may be some nicer way to support this in C# and it may be added in the future, however I think that the integration of this feature would be more complicated than in F#. Also, anonymous types serve similar purpose as tuples (but only locally), so in some cases, you don't really need tuples in C#.
精彩评论