๐ Introduction
Among the bunch of topics that I would like to cover in this post series, one emerged as an immediate candidate these past weeks after having a conversation with one colleague about it, and also after having seen a recent video from @elfocrash in his YouTube channel talking about it, so let's try to explain the context, my preference, and how to apply a rule about it.
At the same time, as always, I would like to encourage you to always keep a respectful point of view with other's coding styles, since they are just a matter of preference, and it never deserve long discussions that are a drop in the bucket.
๐ The context
Since its introduction in c# 3.0 in 2007, the var
keyword has created supporters and detractors indistinctly in its usage. The automatic type inferring was something interesting, using var
then you didn't need to extend the variables declarations horizontally more than needed, avoiding in some cases to declare the type twice:
// Prior to c# 3.0
UserRepository userRepository = new UserRepository(connectionString);
User user = new User();
// Since c# 3.0
var userRepository = new UserRepository(connectionString);
var user = new User();
At the same time, the keyword was a requirement for the definition of anonymous types, a great added feature to the language:
var userDetails = new { FullName = "John Doe", Role = "Basic" };
This flexibility, and simplicity added to the way of coding since c# 3.0 created at the same time some detractors in its usage, arguing mainly the lack of explicitness at a first sight, and from a more purist point of view, considering the nature of c# as a strong typed language, the usage of var
was seen as something allowing developers to code c# at a certain level, as if it was JavaScript.
โญ My preference
I started as .NET developer after .NET 3.5 and C# was released in 2007, so I was born in a world where var
was available and extensively used, and for someone who was coding mainly in Java during my learning period, the recurrent redundancy when typing types, variables names plus constructors or descriptive method names was something that once the var
possibility in c# was known, made me see all of this as redundant and unnecessary.
It is true that the lack of explicitness forces the developer to deduct the type in some scenarios, specially when something is returned back from one method.
private SecurityTokenDescriptor GenerateTokenDescriptor(Claim[] claims)
{
var signingKey = SecurityKeyHelper.GetSecurityKey(_authSettings.SecretKey);
var expiringDate = DateTime.UtcNow.AddMinutes(_authSettings.MinutesToExpire);
var signingCredentials = new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256);
return new SecurityTokenDescriptor
{
Issuer = _authSettings.SiteName,
Audience = _authSettings.SiteName,
Subject = new ClaimsIdentity(claims),
Expires = expiringDate,
SigningCredentials = signingCredentials
};
}
For instance, even though the name of signingKey
is descriptive enough, there's no concise way for knowing the specific type handled, and you are forced to point the cursor hover the variable to see the type.
So given that scenario, the option followed by the detractors of using var
would be something like this:
private SecurityTokenDescriptor GenerateTokenDescriptor(Claim[] claims)
{
SecurityKey signingKey = SecurityKeyHelper.GetSecurityKey(_authSettings.SecretKey);
DateTime expiringDate = DateTime.UtcNow.AddMinutes(_authSettings.MinutesToExpire);
SigningCredentials signingCredentials = new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256);
return new SecurityTokenDescriptor
{
Issuer = _authSettings.SiteName,
Audience = _authSettings.SiteName,
Subject = new ClaimsIdentity(claims),
Expires = expiringDate,
SigningCredentials = signingCredentials
};
}
But, although we somehow achieve more explicitness with the second approach at a simple glance, I have never had this as a problem, since the solution is as simple as hovering over the variable, helped by the IDE.
Otherwise, just because of the need to see it without moving the cursor or deducing, something that seems really unnecessary to me, we introduce redundancy, inconsistency, or let me add, something less orderly.
Why? Because using var
helps pulling off the unnecessary visual noise, the developer has to think less when declaring variables (always var
), and less characters (just three) to achieving more consistent code. Last but not least, its flexibility even allows you to change return types in functions without having to change the declaration: simply var
takes care of it for you.
It is in no way the definitive argument, nor one by which to throw the rest to the ground, but in my humble opinion, the consistency and readiness, as well as during writing, is something with much greater weight than the rest of arguments that I have seen against its usage.
I might finish this section now, but there is another actor that alters my view on the overall equation: the new target-typed new expressions introduced in C#9. This avoids the need of typing the specific types in constructors when the type is already known. So, in that case we are shortening the declaration, but in the initialization instead of the declaration.
//Traditional way
User user = new User();
//var approach
var user = new User();
//new() approach
User user = new();
If we think only in the horizontal length, the new approach is shorter, but it still can create some visual inconsistency when declaring variables. In any case the new Target-typed new expressions feature is something that I found really interesting, and I am not against its usage.
๐ How to apply
I would like to start this last section of the post with a big disclaimer: This is just a matter of preference. The key aspect over this is to agree within the team the standard that makes everybody feel comfortable with, following and stick to it.
csharp_style_var_elsewhere = true
csharp_style_var_for_built_in_types = true
csharp_style_var_when_type_is_apparent = true
The example above demonstrates how to suggest var
over specific types within your .editorConfig file, including primitives. However, you can customize these three values according to your team preferences. Also you can specify the level of severity just by adding :suggestion
or :error
or :warning
at the end of any of them, allowing the IDE to suggest accordingly to the different rules applied.
I hope you liked this post, so please feel free to share your thoughts, opinions and/or experiences as well on the comments section below.
Happy coding! ๐ป
Top comments (2)
Personally, I like (and generally use)
var
. As shown by the photo of books, it makes things a bit tidier and easier to read with a consistence left margin width.But as with everything in programming, it all depends on the use-case.
Agree! The feeling of order is much greater!