📜 ⬆️ ⬇️

C # .NET: Five little wonders that will make your code better. Part 1

Hello, Habrasoobschestvo. I would like to submit to the court of your own translations of the series of articles by Michael Michael Hare (James Michael Hare) "Little C # wonders". So, the first part is in front of you!
These little tips and tricks will make your code more concise, productive and maintainable. Probably many of you know about all or some of them, but ignore them, or simply do not know.

1. Operator ??


This little operator can be extremely useful in some cases. How often does it happen that you have a variable whose value you would like to use, but if this value is null, then you want to replace it with the default value? Suppose you want to assign a string to a variable, but if the string is null, you want to substitute an empty string in place of it:
You can, of course, write a conditional expression using if:
string name = value; if (value == null) { name = string.Empty; } 

Or even better if you use the “?” Ternary operator:
 string name = (value != null) ? value : string.Empty; 

Oh, more briefly, but we can improve this code! In C # there is an operator ??, which is a shortened version of the operator? checking for null:
 string name = value ?? string.Empty; 

Very concise and beautiful! You can write an auxiliary method to trim the string and return null if the string consists only of spaces, so that it can use ?? ..
 public static class StringUtility { public static string TrimToNull(string source) { return string.IsNullOrWhiteSpace(source) ? null : source.Trim(); } } 

This statement can also be used to convert empty strings to the default value:
 string name = StringUtility.TrimToNull(value) ?? " "; 

2.Application of types with as


How many times have you seen similar code:
 if (employee is SalariedEmployee) { var salEmp = (SalariedEmployee)employee; pay = salEmp.WeeklySalary; // ... } 

It is redundant because you perform type checking twice. The first time is a check in a conditional operator, and the second is a type conversion. Every time you find yourself walking this way, prefer type casting with as. This is a convenient casting method, because it returns a reference to the type if the types are compatible, and null if not:
 var salEmployee = employee as SalariedEmployee; if (salEmployee != null) { pay = salEmployee.WeeklySalary; // ... } 

The code reads better, and you avoid double type checking.

3. Automatic properties


We all know about properties in C #, and most know about automatic properties. They turn the following code into two ordinary properties and two private fields:
 public class Point { int _x, _y; public int X { { return _x; } set { _x = value; } } public int Y { get { return _y; } set { _y = value; } } } 

In a much more concise and understandable:
 public class Point { public int X { get; set; } public int Y { get; set; } } 

Much shorter! Whenever you have a property that simply sets or returns the value of a private field, you should prefer automatic properties to ordinary ones, at least not to write a lot of code. All you need is to write a property with accessors that do not contain code, and the compiler will automatically generate fields for you "behind the scenes".
You can also make a property with asymmetric access levels! That is, you can make the automatic property read-only or write-only:
 public class Asymetrical { public string ThisIsReadOnly { get; private set; } public double ThisIsWriteOnly { private get; set; } } 

This makes it easier to create properties that can only be set by the class itself, but can be read publicly, and vice versa.

4. Stopwatch class (stopwatch)


How many times did you want to detect how long a piece of code is running? Maybe you tried to track the average request execution time or other similar information, or perhaps you tried to send a warning message when the method takes more than one second to execute?
You could do this using datetime:
 DateTime start = DateTime.Now; SomeCodeToTime(); DateTime end = DateTime.Now; Console.WriteLine("   {0} ", (end-start).TotalMilliseconds); 

But DateTime is not accurate for this kind of calculation. You can access a higher precision timer through the Win32 API, but this method is more “dirty” and error-prone.
So what should the developer do? Use the Stopwatch class, which is located in the System.Diagnostics namespace. The Stopwatch class simplifies the use of a high-precision timer:
 var timer = Stopwatch.StartNew(); SomeCodeToTime(); timer.Stop(); Console.WriteLine("   {0} ", timer.ElapsedMilliseconds); 

Much more accurate. Note that there is a static method that creates and starts a stopwatch. It is also possible to create a stopwatch with the use of new and run when needed.

5. TimeSpan methods


How many times have you seen code like the following and wondered how long the “sleep” should last?
 Thread.Sleep(50); 

Fifty seconds? Milliseconds? Actually it is milliseconds. But what to do when you stumble upon something like this:
 void PerformRemoteWork(int timeout) { ... } 

What is this time out? Seconds? Minutes? Milliseconds? All the envy of the developers! I have seen timeouts and intervals in BCL and user code, recorded both as seconds and as milliseconds. For this, it is almost always better to use TimeSpan, since it does this in a much less ambiguous way:
 void PerformRemoteWork(TimeSpan timeout) { ... } 

Now you don’t need to worry about units, because they were specified when creating a TimeSpan object:
 PerformRemoteWork(new TimeSpan(0, 0, 0, 0, 50)); 

Ambiguity is eliminated from the point of view of the method itself, but not the calling code. For the calling code will pass 50 seconds? Or milliseconds? It seems we have a similar problem! Some confusion can be caused by the fact that there are five constructors in the TimeSpan class and all of them are ambiguous:
 TimeSpan(); TimeSpan(long ticks); TimeSpan(int hours, int minutes, int seconds); TimeSpan(int days, int hours, int minutes, int seconds); TimeSpan(int days, int hours, int minutes, int seconds, int milliseconds); 

Use static methods of the TimeSpan class. This will avoid the unevenness when creating a TimeSpan object:
 PerformRemoteWork(TimeSpan.FromMilliseconds(50)); 

Now there is no ambiguity, and everything is perfectly readable! No chance of misinterpreting the parameters. By analogy, use the following methods:
 TimeSpan.FromDays(double days); TimeSpan.FromHours(double hours); TimeSpan.FromMinutes(double minutes); TimeSpan.FromSeconds(double seconds); 

So you can specify an interval in a unique way. This also works with static read-only fields:
 public sealed class MessageProducer { private static readonly _defaultTimeout = TimeSpan.FromSeconds(30); } 


Summary


I hope you enjoyed these five little wonders, and I have something to offer you next week. I hope you found at least one that you didn’t know or forgot, and now you can use it!

')

Source: https://habr.com/ru/post/272355/


All Articles