
New Features in C# 7.0 - kruse-tim
https://blogs.msdn.microsoft.com/dotnet/2017/03/09/new-features-in-c-7-0/
======
nxc18
Wow! They seem to be adding lots of the things that make Python feel more
convenient than C#, tuples being big.

Out parameters are going to make some things much nicer. I can certainly see
local functions being useful as well.

Out of all of it, I think the thing I'm most excited about is pattern
matching. Having used F# for a short time, that was the biggest stand-out
feature; it really does make some code much more concise and expressive.

I love C# but lately I've been using Python for my quick-and-dirty work
because in general I find it to be more expressive. It seems like C# 7 might
make me reconsider.

~~~
Pxtl
The big impediment imho between c# and scripting language is the whole Visual
Studio project experience. With Roslyn they introduced the csx format for c#
scripts so you can have a stand-alone 1-file executable c# script, but the
tooling hasn't caught up yet.

I'm using LinqPad for all kinds of one-off scripting jobs and loving it. I was
trying to learn PowerShell for that task but I've finally given up on that.
PowerShell has some great features, but the overall chaotic syntax just kills
me.

~~~
macca321
I think MS should buy LinqPad and give it away for free. It's just an amazing
experience (having the full version is critical though).

~~~
Pxtl
There's a decent F/OSS implementation called CShell (bad name, I know, that's
already a thing)

[http://cshell.net/](http://cshell.net/)

Either way, neither of them run "true CSX files", but their own homegrown
format that predates csx. But it has made me hopeful for the future of C#
scripts.

~~~
macca321
And another called RoslynPad

------
snarfy
I'm probably in the minority, but I'm not really a fan of these new changes.
Some are OK, but a lot of them seem likely to be abused more than used
appropriately.

    
    
         p.GetCoordinates(out int x, out int y);
    

vs

    
    
         var coordinates = p.GetCoordinates();
    

out parameters should be deprecated, not enhanced.

Patterns are OK, but switch statement with patterns...why? I'd much rather do
something like this:

    
    
        class ShapeHandler()
        {
             public void Handle(Circle c)
             {
                 ...
             }
             public void Handle(Rectangle s)
             {
                ...
             }
        }
    
    

The argument for Tuples:

> Custom-built transport type for every method: A lot of code overhead for a
> type whose purpose is just to temporarily group a few values.

I disagree. Before you know it, that 'temporary group' becomes a first class
citizen and deserves its own type. If it's code overhead, I'd rather the
IDE/tooling help me with it than it be built into the language.

Overall these changes make the language more expressive which is good. I just
fear they will be abused more often than not.

~~~
Analemma_
I think C#'s designers make it clear that they don't want you to use out
parameters. They're a hack; they were only included at all to make it easier
to communicate with C/C++ libraries. But now that they're there, they have to
stay because of back-compat - Microsoft definitely does not want a Python 3
situation. They might as well make them as painless as possible for the people
stuck with them because of some library. And at the same time, they should
offer a compelling alternative to out parameters, which they have finally done
with tuple returns.

~~~
voltagex_
I mentioned this in another thread, but I wish they'd tell the Visual Studio
Team not to use them, then - The SOAP and WCF tools will still happily
generate code that requires out parameters.

~~~
Pxtl
People still use WCF? I suffered enough getting one project running with
Windows Configuration Fuckup. Never again.

~~~
ShinTakuya
Some of us are stuck using them as part of legacy systems. We're eliminating
them as we move to a newer stack but legacy code can be quite sticky.

------
ZeroClickOk
What I love in C# is, each update the language gets even faster, far more
natural to write. Soo different of Javascript, where looks you are fighting
against the language first, and then if you win, can develop something useful.
I use js why I need use it, but I hope use c# instead, high hopes with
webassembly, etc

~~~
jfroma
I worked for 6 years on C#, I was C# MVP and I really enjoyed the language.

4 years ago I started to work more with js and then node.js until I stopped
working on c#. Js has been for me a gateway to transition to other languages
and get paid for that. I learned bash, python, a bit of ruby, go, etc.

If I see c# code today I don't understand what it does. Sure every version has
a lot of new very useful stuff but it also introduces noise, "why he used out
x instead of the new shiny out var x, he might not know about it, lets send
PR".

Along the way I have learned to appreciate simpler languages that does not
change that often. Where there are few or just one way to do something.

I think I read an interview to Mitchel Hashimoto (hashicorp) and he said he
choose Go over all languages because it was boring.

A boring and simple language allows you to focus on the problem you are
solving. A language that doesn't change for years allows people to catch up
and master the tool. It also means that you can open a file written by someone
else years ago and understand what it does.

IMHO js was in that sweet spot until ES6.

~~~
ShinTakuya
Not only that but a lot of very questionable programmers use features just
because they're there. C# is becoming like C++ in the sense that it can enable
beautiful code from the good coders and truly terrible code from the bad
coders.

------
hacker_9
So happy _out variables_ are finally a thing, removes such a pain point in the
language, especially when having to write:

    
    
        SomeReallyLongTypeNameICantQuiteRemember data;
        if (dict.TryGetValue(id, out data)) { ... }
    

Now reduced to:

    
    
        if (dict.TryGetValue(id, out var data)) { ... }

~~~
flukus
While it's good in that example, in the real world I'm expecting a tonne of
bad code to use it as a multiple return mechanism.

~~~
JosephRedfern
Surely tuples should get rid of the need for that hack?

~~~
hermitdev
Sure for new code, but I think the concession here is that it provides
convenience for dealing with existing code/libraries.

Additionally, it allows restricting the scope of the variable, like in the
TryParse examples. The output variable in something like "if
(int.TryParse(someString, out var i))" is now scoped to the if block. It
cannot be used in the else, nor inadvertently later in the parent scope.

------
rjbwork
Does anyone else just feel underwhelmed by the pattern matching? It seems like
syntactic sugar over a standard if(x is Type) that doesn't bring a whole lot
to the table other than being able to write more error prone code.

~~~
snowcrshd
Yeah, I was expecting something like what you get in F#.

But maybe it is just the nature of the [C#] language. Still, I think this
looks more readable than if-statements.

EDIT: Maybe it is just a bad example of pattern matching, the one they put on
that page. I'm betting pattern matching works on the added tuple type. That
would be pretty handy.

~~~
rjbwork
Didn't want to do this out of the gates, but now that I've started a
discussion, and folks seem to agree, check out this library I'm working on.

[https://github.com/Jagged/OneOf](https://github.com/Jagged/OneOf)

I've got some more performance improvements and code cleanup in my stash RN
I've not quite finished up yet.

~~~
rjbwork
Forgot to say earlier - Currently being distributed @
[https://www.nuget.org/packages/DiscU](https://www.nuget.org/packages/DiscU)

------
lacampbell
No mention of option types in the standard library. Next time maybe?

The fact that tuples aren't so painful to write and declare is going to make
me use them much more - happy about that.

------
dualogy
Glad to see C# (and ES too in a way) approaching towards F# (& co.) inch by
inch with every release. Next and final step, introduce optional "indentation
layout" to get rid of braces and semis and I'm a happy camper. FP through the
backdoor! =)

~~~
lacampbell
I'm wondering why the C# team is so keen on pattern matching - I feel like
multiple dispatch would suit the language more and accomplish much the same
thing. But C# is a weird beast in some ways - a pure OO language that keeps
introducing features to make writing getters and setters more and more
convenient.

Maybe I just need to move on with the times. I still see a lot of value in OO,
but it's clear it's not at all in vogue. I am glad that functional ideas -
particularly immutable data, and anonymous functions - have come into the
mainstream. But I don't feel the need to throw the baby out with the bath
water.

~~~
dualogy
> I'm wondering why the C# team is so keen on pattern matching

It's kind of a pre-condition (though not in the current initial limited
variation) for the introduction of Algebraic Data Types (as F# & co. have
them), which I'd still be missing in C# if I had to get working on a C#
codebase (might happen again soon, I just don't get any Haskell enquiries in
my freelance channels =)

~~~
lacampbell
With multiple dispatch, you could already use the existing way of having sum
types - class hierarchies - without introducing a second kind.

I just don't see why you want both inheritance and ADTs in the same language.
But it's entirely possible I'm missing something, I'm an amateur PLT
enthusiast at best.

~~~
dualogy
Would just be syntactic sugar anyway, F# surely compiles its ADTs and
parametric polymorphism down to something supported in MSIL bytecode.. but
potentially powerfully productive "sugar", any highly expressive language is
80-90% sugar (just the right kind) over a much smaller intermediate core
language of way fewer actual primitives

------
partycoder
Looks similar to the Scala syntax: [http://docs.scala-
lang.org/tutorials/tour/pattern-matching.h...](http://docs.scala-
lang.org/tutorials/tour/pattern-matching.html)

I wonder if there will be a way to do something like case classes in C#.

~~~
tintoy
I think they're still working on that:

[https://github.com/dotnet/roslyn/blob/features/records/docs/...](https://github.com/dotnet/roslyn/blob/features/records/docs/features/records.md)

~~~
partycoder
Nice. I hope it's interoperable with F#

------
kovrik
As a Java developer, I am really jealous!

~~~
Kenji
As a C/C++ developer, C# feels like unreachable high level heaven. But then
again, I prefer my code to have no garbage collector, be portable without any
problems and have very high performance. So, C++ it is. If I was writing a
Windows-only GUI app with no resemblance of realtime requirements, I would
only use C#.

~~~
pjmlp
Across how many compilers and operating systems is your code portable without
any problems?!

~~~
vvanders
When written with discipline C++ is very portable. I've worked on codebases
that spanned devices with ~8mb of memory to full-blown desktop PC and
arches(x86/MIPS/ARM/PPC just to name a few).

~~~
raverbashing
Across devices it seems it is very portable.

Now, across compiler vendors and versions it is hard

~~~
Impossible
Generally speaking when you are targeting that wide of a range of devices you
are targeting a wide range of compilers. It requires some discipline but it's
far from the hardest thing in the world assuming you are regularly building
and testing for all platforms. I'd say that most major C++ applications or
libraries compile in Clang, GCC and MSVC without issue and often build for
less common targets as well (icc, nvcc for cuda support, etc.) Things
definitely get harder when you move to weirder embedded platforms.

~~~
vvanders
Yup, we targeted GCC, MSVC, plus a few proprietary compilers. As long as you
stick to a reasonable set of features(which you should anyway for sanity
reasons) it works pretty well.

Having a good CI is a must though but it's not nearly as hard as porting an
old codebase backwards.

------
paulmd
Man I used to love C# so much - and then I realized what a godsend
Maven/Gradle were. I still think C# is the better language and I'm biding my
time - is there a decent Maven/Gradle equivalent for C# yet?

~~~
kirse
Pick up some F# and use FAKE / Paket? I'm not sure I'd call Maven a "godsend"
though, it has its own class of annoyances.

[http://fsharp.github.io/FAKE/](http://fsharp.github.io/FAKE/)

[https://fsprojects.github.io/Paket/](https://fsprojects.github.io/Paket/)

~~~
paulmd
It definitely does, I think Gradle is better... but it's still better than
NuGet.

------
TazeTSchnitzel
I like that new mainstream languages, and updates to major existing languages,
are bringing in a lot of ideas from functional programming languages.

Perhaps the C# of tomorrow will look like the Haskell of today.

~~~
sdegutis
But then what would the Haskell of tomorrow look like?

~~~
mee_too
Like C# of yesterday, after people realize they can put all their program code
in a single IO monad for ultimate power and flexibility :)

------
fdsfsafasfdas
Man, if C# got case classes I'd dump scala for life.

~~~
edko
I wouldn't just yet. The platforms that you can reach with Scala, including
JS, and soon LLVM, plus all the goodies that are being developed in Dotty, are
pretty compelling for me to stay. Scala keeps getting better and better. It is
very exciting to see that other languages, like C#, also keep adding excellent
features.

~~~
shakna
I don't like Scala much, a personal preference, but the research behind Dotty
is utterly amazing, and when it becomes ready for prime time, it'll be a
killer feature.

DOT is some great math, letting them bring simplicity and a ton of high level
features to the compiler with very little cost.

------
macca321
For anyone who is disappointed at the lack of exhaustive matching /
Discriminated Unions, please try out my library OneOf*
([https://github.com/mcintyre321/OneOf](https://github.com/mcintyre321/OneOf)).
Hopefully something similar will be brought into C# soon, but in the meantime,
these libraries provide fairly idiomatic substitutes.

Also, ValueUtils
([https://www.nuget.org/packages/ValueUtils/](https://www.nuget.org/packages/ValueUtils/))
is nice for making value types.

*or one of the many alternatives ([https://www.nuget.org/packages?q=discriminated+unions](https://www.nuget.org/packages?q=discriminated+unions)) e.g. SuccincT, DiscU

------
candl
I wish C# had standalone functions without needing to wrap them in classes.

~~~
Nition
It'd never pass code review on Hacker News but the classic C# hack for that is
just to make a class called Global or whatever and throw your must-be-
everywhere functions in there.

~~~
ruleabidinguser
c++ namespaces are so great for this. Don't know why theyre not available in
most languages.

~~~
svick
Too bad the standard library didn't get the memo and shoved everything into a
single namespace :-)

------
jejones3141
Any idea when Mono will support C# 7.0?

------
ezekg
Been learning C# as I learn Unity/game development and I'm really excited to
see local functions, tuples and destructuring coming in 7.0.

~~~
adamrezich
Too bad you won't see Unity supporting C# 7.0 anytime soon... :(

------
redleggedfrog
This might be the most exciting group of new features since the beginning of
C#. Those tuples...seriously sexy.

But, as much as I love C# (I changed jobs so I could work in it) this just has
a pungent code smell to me:

p.GetCoordinates(out var x, out _); // I only care about x

Ug, some random underscore? I'm no language designer, but something maybe
could have been done better here? It just looks fugly to me.

~~~
johncolanduoni
It's pretty common in languages with pattern matching to use underscore as a
catch-all (ML family, Haskell, etc.). I'm not sure how the underscore is a
code smell; if you want wildcard patterns without throwing a bunch of unused
variables into scope (which can definitely lead to non-obvious bugs), you have
to use some symbol.

~~~
redleggedfrog
Mostly like if I submitted some code for review and peppered it with
underscores because "I don't care about those variables" I'm pretty sure it'd
come back to me with a remark about starting to care.

At the point your writing code you don't care about, something might be wrong.

~~~
bschwindHN
When working with an object, you don't always care about all of its
properties. If it's packed in a certain way (tuple, Optional wrapper, etc.)
that is easy to unpack with destructuring, then you might use an underscore to
say "this is how it's structured, but I don't care about the _particular_
value it has so please don't bind it to a variable."

If you bound it to a variable and didn't use it, it'd be the same as declaring
an unused variable.

------
unsignedint
I do a lot of coding in few different languages regularly (C#, Python, JS
mainly) but what I find is that it is the language I feel enjoyable. Although
part of that is probably because of tooling (Visual Studio, Visual Studio
Code) and also features like LINQ.

------
phaedrus
A long time ago I tried to use a throw in a ternary expression in C++ (e.g.
"return is_good ? value : throw;") and it caused an internal compiler error!
Really cool to see that it's now a feature of C#.

------
lefstathiou
Are there any c# free lancers on this thread? Our company is exploring the use
of the technology for some data projects. If interested in discussing please
reach out: leo at finsight dot com.

------
robbyking
Having left C# for iOS development a while ago, it's really interesting to
come back and see how many features (tuples, discards, local functions, etc.)
have made their way into both languages.

------
sremani
Solid features, Pattern Matching and Local methods are favs!!!

~~~
tracker1
Really liking the extras with Tuples/Destructuring... that was always a pain
point imho with dealing with Tuples previously. Would still love a regexp
literal though.

------
jsmeaton
These all look great, especially tuple literals. I wonder why they chose to
make tuples mutable though. Can anyone answer that question?

~~~
louthy
They're not. The type ValueTuple is a value-type.

~~~
Pxtl
While value-types are recommended to be immutable, it is not mandatory.

------
gigatexal
As a hobbyist python developer it's nice to see c# take some of the good parts
of python.

------
maxxxxx
If they only added deterministic constructors the language would be perfect
for me.

------
starik36
Local methods are really cool, but kind of remind me of GOSUB in QuickBasic
from back in the day. It was considered an anti-pattern, if I remember
correctly.

~~~
int_19h
Local methods are literally nothing like GOSUB. For starters, GOSUB was
originally global, it was only in later structured versions of BASIC (like QB
or VB) that you could have functions with local labels, and therefore local
GOSUB.

And the reason why GOSUB was an anti-pattern was not because it was local, but
because it was so low-level. It was not really a function call - it changed
the current instruction pointer to a new statement _in the same function_ (so
you didn't get a new execution frame etc), and pushed original instruction
pointer onto its own internal stack, from whence you could then return to
(effectively, GOTO) it with the RETURN statement. Because it had no execution
frame, it also had no provision for passing arguments. And because it was the
same code, there were no boundaries - you could flow into the section of code
that was meant to be GOSUB'ed into without the use of GOSUB, and you could
flow back out without RETURN. E.g.:

    
    
       foo = 1
       IF foo THEN GOSUB bar
       PRINT "No GOSUB"
       bar:
       PRINT "Inside bar"
       IF foo THEN foo = 0: RETURN 
       PRINT "No return"
       

On the first run, this will do GOSUB, you'll see "Inside bar", then the flag
is reset and we return to the point where GOSUB is invoked. But then the
natural code flow will pass the "bar" label, and all that code is executed
again, except this time it doesn't RETURN, but instead just keeps flowing on.

So, basically, there's an utter lack of structure here. There's no matching of
GOSUB and the corresponding RETURN - indeed, there may not even be a
corresponding one, or there may be many, and the same RETURN can be reached
via GOSUBs through different labels (and will return to wherever the GOSUB
came from). If you RETURN without any GOSUB on the return stack, that's a
runtime error, not a compile-time one. If you GOSUB without a RETURN, it's not
an error, but you will eventually overflow the stack if you keep doing it. And
so on.

So, it's a very messy mechanism that dates back to pre-structured days of
BASIC. That's the only reason why it was discouraged why BASIC got
SUB/FUNCTION.

~~~
starik36
Ah, thanks for the explanation. Your memory is certainly much better than
mine!

