Live data from Hacker News

What’s New in C# 7.0

blogs.msdn.microsoft.com

251–260 of 278 posts

Re: What’s New in C# 7.0

#251
post #199

Earlier quoted context omitted.

C++ doesn't have this problem, because it doesn't allow virtual function templates. For that matter, it doesn't allow any templates across ABI boundary, except when you manually instantiate them (extern template) - and then only for those explicit instantiations. So it is effectively impossible to have a generic C++ API using templates that is not statically linked.

Of course it does, as I said I was doing that. Borland C++ for Windows 3.x had an initial implementation for templates as they started to be discussed at ANSI and also supported exporting classes across dlls, providing both producer and consumer were Borland C++.

How exactly did that implementation work for templates?

Re: What’s New in C# 7.0

#252

Earlier quoted context omitted.

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…

Hi, thanks for taking the time to comment.

> You don't use the first var out complete in the TryGetValue, right?

There is only one complete variable; we declare it in TryGetValue, and it's definitely used in the last line of the while statement, but might first be used after the if statement.

> And the Student c'tor returns itself as an out parameter?

The Student constructor does not return itself as an out parameter, rather it returns an object that can modify an internal list of courses.

The idea is that when we iterate through a result set from a database, some of the rows are going to correspond to a new student object, and some are going to correspond to a course that belongs to the student. Crucially, we are only allowed modify the Student object (or whatever) during iteration, and the collection that we return will only contain immutable/unmodifiable Student objects.

I've used this technique to populate deeply nested structures (lots of joins and nested joins) using only one query.

> 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)
Just to be clear, the reason that I cannot do that is because the Student object might not be completely "hydrated" until we finish iterating through the result set, because it might contain a bunch of nested objects that also need to be instantiated from one or more DB records.

> Also, why not enforce your student ID constraint in SQL instead of putting everything in a dictionary only to take it back out again?

I'm not quite sure I understand this (which is probably my fault), but rest assured that we use nothing but SQL (specifically, DDL) to enforce data integrity.

Re: What’s New in C# 7.0

#253

Earlier quoted context omitted.

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…

[deleted]

Re: What’s New in C# 7.0

#254
post #82

Earlier quoted context omitted.

Did you guys look into alternative syntax for return types? It really is a huge eyesore, and impediment to reading, when you have more than just a typename and a couple of modifiers like * and [] attached to it. With tuples especially, it's even worse, because the method name gets squished between two very similarly looking ()s, which is very different from how methods have historically looked in code. If I were scan…

What would you suggest? public TResult SomeMethod() where TResult : (string name, int id)

The most obvious approach would be to repurpose C++ syntax, since it's already been around for a while, and C# syntax is generally pretty close to C++ in many respects. So:

  public SomeMethod(bool b) -> (string name, int id) { ... }
However, this may be undesirable due to confusion with => for lambdas and expression-bodied methods, especially in:

  public SomeMethod(bool b) -> (string name, int id) => ...
: is the next obvious candidate, and would unify the syntax with TypeScript and many other languages. But given that it's already used for labels and named arguments, I'm not sure there's enough room there to reuse it also for types.

:: is another decent choice in terms of familiarity coming from other languages (Fortran, Haskell etc). But, unfortunately, it's already taken for extern alias, and I don't think this could be easily disambiguated in many contexts.

Now, if this is narrowly scoped to method return type only (i.e. we're not trying to invent a syntax that could later be used in a similar way to swap the type and the name in other places, like arguments and variables), and only as a fallback for when the usual "Type Name" arrangement has poor readability, perhaps take a hint from Ada and reuse "return"?

  public SomeMethod(bool b) return (string name, int id) { ... }
A tad verbose, but if it's intended to be used sparingly, primarily with tuple-returning methods and deeply nested generics, I think that's okay - tuples themselves are pretty verbose when components are named.

Or maybe borrow "as" from VB? It looks like it could be extended to other kinds of declarations in the future in a straightforward manner, without conflicting with its existing use for casts:

  // Just for method return types
  public SomeMethod(bool b) as (string name, int id) { ... }

  // For everything
  public SomeMethod(b as bool) as (name as string, id as int) {
    var x as float;
    TryFoo(out var y as bool);
    ...
    switch (obj) {
      case foo as Foo:
        ...
    }
  }

Re: What’s New in C# 7.0

#255

Earlier quoted context omitted.

> CSharp once again showing it is the best language in terms of features and improvements. That's a pretty sweeping generalization. Most of the headline features in the article are already in other languages e.g. Scala.

The difference being CSharp is actually used by a large number of people. Scala is not even in the top 10 used languages [0]. [0] http://www.tiobe.com/tiobe-index/

Scala is consistently #15 or #16 in various measurements. Just not in TIOBE as they decided to use the wrong search terms to look for, so TIOBE doesn't provide useful information in this case.

Re: What’s New in C# 7.0

#256

Earlier quoted context omitted.

>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 I hope there are better examples of Scala's syntactical advantages than this one, because it seems like the 'egyptian-style' vs 'next line style' brace bracket debate...

Yes there are plenty. The correct order of type declarations just ties in with the better syntax for generics and leads to an easier to read, more consistent language.

Interesting; thanks. F# and Scala are pretty high on my to-learn list.

Re: What’s New in C# 7.0

#257
post #154
post #149

Earlier quoted context omitted.

They run deterministicaly though, making them much safer. I've done migrations with these tools that would be impossible with redgate, clients could be several months out of date since an upgrade and the migrations would just work. I've seen redgate/ssdt need manual coaching after just a few weeks. I also think your over estimating the popularity of red gate. A minority of places use it, whereas a lot use EF migratio…

Literally every place I've worked uses red gate. I've never had an issue with it, If you make sure your database is constantly up to date. So changes are small.

> Literally every place I've worked uses red gate.

I've had the opposite experience, I've only been at one place that used it and a couple that considered it.

> I've never had an issue with it, If you make sure your database is constantly up to date. So changes are small.

This is not an option in many places, if you have 3 month release cycles for instance (although I favor continuous deployment). Another is when you have apps installed on site, some clients can be multiple versions behind.

Re: What’s New in C# 7.0

#258

Earlier quoted context omitted.

What would you suggest? public TResult SomeMethod() where TResult : (string name, int id)

The most obvious approach would be to repurpose C++ syntax, since it's already been around for a while, and C# syntax is generally pretty close to C++ in many respects. So: public SomeMethod(bool b) -> (string name, int id) { ... } However, this may be undesirable due to confusion with => for lambdas and expression-bodied methods, especially in: public SomeMethod(bool b) -> (string name, int id) => ... : is the next…

I like the as syntax, it may conflict with casting though when used on variables.

    public SomeMethod(bool b) -> (string name, int id) { ... }
When was this added to c++? I think I need to brush up on my lower level skills.

Re: What’s New in C# 7.0

#259
post #127

Earlier quoted context omitted.

Did you ever maintain vb6 apps? Because I still want to cry thinking about the times I've had to.

I have. If they were designed well then they are normally OK to maintain. If they were developed badly then they can take extra effort. Much like any other project in any other language. If you had an large old Vb6 project build using MVP pattern you would be laughing.

    Much like any other project in any other language.
Yes, you can write good or bad code in any language. But some languages have an endemic culture of not caring about good code. IME, VB is one of them, as is PHP.

All the VB6 code I've seen has been a random mashup of databinding directly to the and click handling. The tools encouraged this approach.

Re: What’s New in C# 7.0

#260
post #258

Earlier quoted context omitted.

The most obvious approach would be to repurpose C++ syntax, since it's already been around for a while, and C# syntax is generally pretty close to C++ in many respects. So: public SomeMethod(bool b) -> (string name, int id) { ... } However, this may be undesirable due to confusion with => for lambdas and expression-bodied methods, especially in: public SomeMethod(bool b) -> (string name, int id) => ... : is the next…

I like the as syntax, it may conflict with casting though when used on variables. public SomeMethod(bool b) -> (string name, int id) { ... } When was this added to c++? I think I need to brush up on my lower level skills.

It was added in C++11 when they added decltype(), so that you could reference arguments when computing return type. It's slightly different though, in that you need to specify the return type in the usual position as "auto" first, and then you can use "->" after the parameter list. So:

  template
  auto foo(A1 a1, A2 a2) -> decltype(a1 + a2) {
    return a1 + a2;
  }
Post reply on HN