Live data from Hacker News

What’s New in C# 7.0

blogs.msdn.microsoft.com

231–240 of 278 posts

Re: What’s New in C# 7.0

#231
post #7

It looks like they've added a lot of rope to hang ourselves with typos. int myvar, I; foo(out int mvar); // oops, not myvar; maybe caused by a refactor? bar(out *); // oops, not I; was up too late coding And so on. Things like this would be easily missed when reading code at-a-glance, and it's this sort of bug that arises often in languages that allow implicit declaration of variants.

Hi there, C# language designer here. I don't really see your example in that way. Let's start with the latter one first: > bar(out *); // oops, not I; was up too late coding I'm not sure how this situation is any differnet from any other case where you need to pass some variable, and you pass the incorrect name. This is already possible all over the language. For example, you might have written "bar(out J)" when you…

> I'm not sure how this situation is any different from any other case where you need to pass some variable, and you pass the incorrect name.

It's a wildcard. Passing in any other variable name would ideally raise an error about the use of an undeclared variable or a mismatched type. The use of a wildcard disposes of those errors.

> the mispelled name problem is really no different than what you might experience today

Not quite; your modified examples includes two declarations on their own lines. Being on their own line gives them greater visual presence at-a-glance than the new syntax which buries the declarations within a parameter list.

Worth noting is that my trivial example managed to confuse at least one reader who was unable to see the issue[0].

> All declarations are explicit.

While true, you've muddied the lines a little by moving declarations into the syntax of other expressions. Where previously a declaration sat on its own line or at the beginning of an assignment, they may now be peppered throughout the syntax in ways that are not so easy to observe at-a-glance.

0: https://news.ycombinator.com/item?id=12356681

Re: What’s New in C# 7.0

#232
post #225

Earlier quoted context omitted.

I'm probably missing your point, but public static IList FindEphraimitesToKill(IList ephraimites) { var ephraimitesToKill = new List (); foreach (var ephraimite in ephraimites) if (ephraimite.Speak("shibboleth") == "sibboleth") ephraimitesToKill.Add(ephraimite); return ephraimitesToKill; } or: public static IList FindEphraimitesToKill(IList ephraimites) { return ephraimites.Where(e => e.Speak("shibboleth") == "sibbol…

The thing is, though, would those be allowed by style guides at the enterprise companies where C# is most common? The C# style guide of a former employer of mine (an enterprise C# user) forbids both of these snippets because of the unbraced statements in the former and the LINQ and lambdas in the latter. But admittedly I don't know what's common among C# users, so maybe they were in the minority.

The brackets, maybe. Preferences for brackets for single lines vary. I personally don't like them, but many code style guides (including MS's) recommend them.

The LINQ version should be allowed almost everywhere that has a good development group. Sometimes LINQ queries can get hairier than the equivalent foreach, but I've never worked anywhere that would frown upon the shorter/cleaner LINQ.

Re: What’s New in C# 7.0

#233
post #2

Out variables seem like a mis-feature, especially when they are adding a better alternative (Tuples) in the same release. It's great to finally have tuples, but the c/java style syntax is showing it's age compared to something like scala which has return type declarations at the end, which I find much more readable. Literal improvements will be a godsend for writing database migrations. Ref returns and locals look li…

Out parameters are also useful in constructors. I often use them as a way to limit the scope in which an object can be modified, which lets me have mostly immutable objects. IEnumerable GetStudents(SqlCommand cmd) { var rdr = cmd.ExecuteReader(); //select * from student left join courses on... var memo = new Dictionary (); //Completion lets us add courses to a student while(rdr.Read()) { if(!memo.TryGetValue(rdr.GetI…

So I'm taking a look at this line:

  if(!memo.TryGetValue(rdr.GetInt32("student_id"), var out complete)
    memo.Add(new Student(rdr out complete).ID, complete);
I think I understand your point, but I found this code really hard to read. You don't use the first var out complete in the TryGetValue, right? And the Student c'tor returns itself as an out parameter?

If I understand you correctly, you like this because you don't have to declare a new student before you add it? I.e. the alternative would be

  if(!memo.ContainsKey(rdr.GetInt32("student_id")))
    var student = new Student(rdr);
    memo.Add(student.ID, student);
I guess I would prefer this over the former. Also, why not enforce your student ID constraint in SQL instead of putting everything in a dictionary only to take it back out again? That would simplify your code to the point of just being a map from rdr->Student. Furthermore, if all I had was the Student c'tor, I would never guess that was the intent of the out parameter. This seems more anti-pattern than pattern.

I would rather put a simple IEnumerable in front of SqlDataReader so that you could just do:

  foreach(var row in rdr) yield return new Student(row)
This doesn't obviate your use case, however, which is to inline a variable where it's needed in multiple places in that line because you can save yourself an explicit declaration. In this case, however, I think that the increased readability justifies the explicit declaration.

Re: What’s New in C# 7.0

#234

What's the point of GetCoordinates(out var x, out var y) over destructuring assignment like var x, var y = GetCoordinates(); the former looks completely backwards.

I much prefer your second example. In fact, surely tuples would help in this situation?

eg. in C++: tuple x = GetCoordinates(); or auto x = GetCoordinates()

Much easier to see the output. I maintain enough old old C++ code and don't like seeing GetCoordinates(int x, int y) or x in COM-land any more.

Re: What’s New in C# 7.0

#235
post #32

Wow, lot's of great stuff! I especially like local functions, I'm all for breaking up complicated methods into several methods to simplify and clarify syntax... but it always felt weird that all those methods where on an class scope even though they only were relevant for that method. This resulted in many cases that those methods needed to be broken out into their own class... which is the way to go some times but f…

I would have thought use of a Func or a lambda would have been appropriate instead of a local function?

Re: What’s New in C# 7.0

#236
post #178

Earlier quoted context omitted.

I'd say Swift is more or less in line with C# with regards to functionality. Many new features added to C# seem to already exist in Swift. Swift could use some async/await mechanism en sometimes it's a bit annoying to typecast simple types for calculations, but otherwise Swift is a really sweet language to work with. Nonetheless C# is a nice language. I enjoy writing C# code, just as I enjoy writing Swift code.

I'd disagree with you to be honest. Swift is still in it's infancy, and while it copied many of it's features from CSharp, it did so poorly and even now they continue to make breaking changes to their standard with each update.

Yes I have noticed this. It is interesting observing the changes to Obj-C just to keep up with the developments in Swift-land, when Swift itself is changing so frequently.

Re: What’s New in C# 7.0

#237

CSharp once again showing it is the best language in terms of features and improvements. Great job all round by the designers.

C# > C++?

I was hoping for deterministic lifetimes in this release.... just kidding. Must be me being used to C++'s RAII and useful destructors.

I believe your comment is a huge generalisation.

Re: What’s New in C# 7.0

#238
post #168

I tend to avoid using switch/case for quite irrational reasons. The break statement just looks wrong and I can't layout the code in a way I find at all pleasing. I'll almost always use a sequence of else if conditions instead. In my ideal world, it'd look like... switch (x) { case 1: { /* ... */ } case 2: case 3: { /* ... */ } } And before anyone points it out, switch is the same as else if when the thing being compa…

The problem is "falling through" the case statements. You can do this in C++ and C, which is really useful. You can't do this in Swift, and it's incredibly annoying.

Break is there for a good reason.

Re: What’s New in C# 7.0

#239
post #171
post #168

I tend to avoid using switch/case for quite irrational reasons. The break statement just looks wrong and I can't layout the code in a way I find at all pleasing. I'll almost always use a sequence of else if conditions instead. In my ideal world, it'd look like... switch (x) { case 1: { /* ... */ } case 2: case 3: { /* ... */ } } And before anyone points it out, switch is the same as else if when the thing being compa…

Same here, plus I think the parent brakes are noise, can the compiler just know that the switch statement ends on last case?

No, as in some instances you may wish to do the same thing for two case statements, so you need it to fall through case1 into case2.

In other situations, you really don't want it to do that, so a break is required.

How would the compiler know the difference? Note that you can't "fall through" cases in Swift, and it is irritating. It stops you using the same code for two case statements - you have to duplicate it or put it into a function.

Re: What’s New in C# 7.0

#240
post #225

Earlier quoted context omitted.

I'm probably missing your point, but public static IList FindEphraimitesToKill(IList ephraimites) { var ephraimitesToKill = new List (); foreach (var ephraimite in ephraimites) if (ephraimite.Speak("shibboleth") == "sibboleth") ephraimitesToKill.Add(ephraimite); return ephraimitesToKill; } or: public static IList FindEphraimitesToKill(IList ephraimites) { return ephraimites.Where(e => e.Speak("shibboleth") == "sibbol…

The thing is, though, would those be allowed by style guides at the enterprise companies where C# is most common? The C# style guide of a former employer of mine (an enterprise C# user) forbids both of these snippets because of the unbraced statements in the former and the LINQ and lambdas in the latter. But admittedly I don't know what's common among C# users, so maybe they were in the minority.

5-6 years ago enterprise guidelines preventing LINQ/lambda's were more common. Current C# practices for enterprise companies(familiar with 6+ fortune 500's, have not seen or heard of them being banned in the last 4 years) definitely allow lambdas and LINQ.

The "required brackets" is more common but I think it's a good rule :). Readability is only slightly hindered by the extra brackets, but I've seen quite a few errors from

if(shibboleth)

    DoSomething();

    DoSomethingElse();
Post reply on HN