Hacker News new | past | comments | ask | show | jobs | submit login

To me, the benefit of "Target-typed new expressions" is more with bringing consistency to class-scope member declarations and method-scope member declarations, so these two can look the same, and a programmer only has to read one way of declaring new members in C#:

  public class MyClass {
   private readonly MyDependency _myDependency = new();

   public void MyMethodThatDoesWork() {
       MyVariable variable = new();
   }
  }
As opposed to the (now old, IMO) var syntax/Java-like syntax mixture:

  public class MyClass {
   private readonly MyDependency _myDependency = new MyDependency();

   public void MyMethodThatDoesWork() {
       var variable = new MyVariable();
   }
  }
Edited for HN formatting.



I can't see var going anywhere, many times you aren't directly creating a new object, but getting a generated object from something ( like linq) which tends to have more complicated type signatures.


Agreed that `var` isn't going anywhere, but this feature's best use case is with complex generics/enumerables and things like anonymous tuple types. For example:

  // old:
  var x = new List<KeyValuePair<string, int>>
  {
    new KeyValuePair<string, int>("a", 1),
    new KeyValuePair<string, int>("b", 2)
  };

  // new
  var x = new List<KeyValuePair<string, int>>
  {
    new("a", 1),
    new("b", 2)
  };


Another option if you're still on .NET framework is to use a collection initializer extension method. I add a comment when I do this and place the extension method in a separate namespace.

    // ListExtensions.cs
    internal static class
    ListExtensions
    {
        public static void Add(this List<KeyValuePair<string, int>> list, string key, int value)
        {
            list.Add(new KeyValuePair<string, int>(key, value));
        }
    }
    
    // new w/extension method
    var x = new List<KeyValuePair<string, int>>
    {
        {"a", 1},
        {"b", 2},
    };


Wow, when I (only a C# dabbler) read about this feature in the article I thought it sounded incredibly silly, but this really sells it. Was there really no better way to create tuples before?


You could create tuples with `Tuple.Create("a", 1)` since at least .NET 4, if not 3.

Since C# 7 you can also create tuples using just `("a", 1)`. But tuples are not KeyValuePairs. So the new "new" syntax will be very helpful in a lot of cases.


I really don't understand why they haven't added implicit conversion operators between the modern ValueTuple and the legacy value-types like KeyValuePair, Tuple, and Pair, grumble. It's a non-breaking change!


Adding that is potentially a source breaking change. Admittedly an easy enough one to address, and they are more willing to make such changes in CoreFx, then they historically were, so it is not impossible that they could decide to do it.

For an example of this being a breaking change. Let's say that B is some other type implicitly convertable to A.

The following two method overloads exists:

    void Method(A a, ValueTuple<int,int> vt);
    void Method(B b, Tuple<int, int> t);
Right now `Method(SomeB, (4,5))` compiles fine, but if your proposed conversions were added, it would suddenly yield `CS0121: The call is ambiguous between the following methods or properties:...`.


Tuple is not a value type. And this means that they won't add an implicit conversion, because right now a major focus of .NET and C# is also performance. and this conversion would mean an implicit heap allocation. They'd rather avoid adding features of this sort as I understand it.


C# (as of 7.0) has pretty nice tuple syntax that supports all things you expect (deconstruction, etc):

https://docs.microsoft.com/en-us/dotnet/csharp/language-refe...

But the situation here is that the type KeyValuePair is older than that and isn't a tuple.


> Was there really no better way to create tuples before?

Here are some other options for code like the grandparent post. I tend to either live with the boilerplate or use a local function.

1. Use a collection initializer extension method (https://news.ycombinator.com/item?id=26641997).

2. Define a local helper function.

    KeyValuePair<string, int> KeyValue(string key, int value)
    {
        return new KeyValuePair<string, int>(key, value);
    }

    // new w/local function
    var x = new List<KeyValuePair<string, int>>
    {
        KeyValue("a", 1),
        KeyValue("b", 2)
    };
3. Use an array of C# 7 tuples and convert them in a loop or query.

4. Use generics to infer the argument types à la Tuple.Create. This technique can be helpful for using anonymous types with collections.

    //KeyValuePair.cs
    internal static class KeyValuePair
    {
        public static KeyValuePair<TKey, TValue> Create<TKey, TValue>(TKey key, TValue value)
        {
            return new KeyValuePair<TKey, TValue>(key, value);
        }
    }


    // new w/helper class
    var x = new List<KeyValuePair<string, int>>
    {
        KeyValuePair.Create("a", 1),
        KeyValuePair.Create("b", 2)
    };


Oh true, there are still use cases where it's valuable. `out var ` also comes to mind.


I hate hate hate var.

Sure, in your own IDE, and reading the code you just wrote, no problem. But when doing code reviews and jumping all over, I want to see the type right there. Nothing more frustrating than reviewing a PR with var's all over. This isn't even up for debate anymore... No more var!

It is frustrating to still see var as the recommended way by Microsoft... You can even put in a rule to format the document and add explicit types as well on save. So complicated type signatures for linq aren't a problem!


This is completely the opposite of my own experience. Using “var” makes the code easier to write AND easier to read. The code becomes decluttered from all the mess of types everywhere and you can read what it is actually doing.

Anyone who names their variables properly should have no problem telling what kind of types are being worked with anyway. And in the rare case you absolutely need specifics, they’re just a tooltip away.

I always find these arguments against “var” somewhat absurd because those same programmers work with fields and properties and methods from other classes all the time, and none of those requires you to write the type.

For an example, if you were to access “someExternalThing.bigRedTrain”, the type of “bigRedTrain” would be written nowhere in the current class. I fail to see how using “var bigRedTrain” is any different.


Can't disagree more. var improves readability so much that I can't imagine reviewing code anymore with unnecessary type declarations everywhere.


Every time you write something like Foo.Bar, the type of the value returned by Foo is implicit - i.e. it's exactly like var. Do you never dot-chain properties and method calls? If you do, why should it be any different when some intermediate step in the chain gets a name?


  MyFluffyGenericType<WowThisIsFun<MeToo>, MoreStuff> x = myVendorsStupidContract.SomeInsaneType;
vs

  var x = myVendorsStupidContract.SomeInsaneType;


> Nothing more frustrating than reviewing a PR with var's all over.

ooh you gotta try reviewing your PRs within visual studio [1] (and be sure to use VS internal diff tool as well) - var is no longer annoying with intellisense

[1] https://github.com/github/VisualStudio/blob/master/docs/usin...


There's a reasonable convention of specifying full type for a variable that is returned from a method where it's not very clear what the method returns without looking up method signature. This usually means that the method name can be is not descriptive enough, but there are case where you can't really fix that. Other than that, I think var definitely is a huge benefit for readability and overall code design.


Even then, you only see the type signature when you are initializing the variable, not every time you use it.

If you really want to see type signatures everywhere, you should use something like Hungarian notation which embed type information in the name. And you should disallow method chaining and having methods or properties as parts of expressions.

But I would recommend just using an IDE instead.


It’s definitely up for debate and since “use var everywhere” is the default ReSharper setting I suspect your preference is the minority position.


This kind of thing is really quite common in languages though. You have to understand that this is quite subjective.


https://ericlippert.com/2009/01/26/why-no-var-on-fields/

Eric Lippert blogged about that like 12 years ago (when var just came out) interestingly there's a c#9 epilogue now at the bottom of the post.




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: