// 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)
};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.
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:...`.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.
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)
}; // 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},
};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!
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.
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...
MyFluffyGenericType<WowThisIsFun<MeToo>, MoreStuff> x = myVendorsStupidContract.SomeInsaneType;
vs var x = myVendorsStupidContract.SomeInsaneType;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.