It is not just practice that will help you master C#. Using tools to look under the hood will accelerate your understanding of various language features and helps you write better, more efficient code. Sharplab.io is one such tool that will help you to quickly learn and understand certain C# language features. You can use this tool to show you "lowered" C# code.
What is Lowering?
Lowering is where the compiler converts high-level language features into simpler, low-level features. Lowering has the added benefit for compiler writers in that they can implement new language features without needing to change the underlying CIL or Common Intermediate Language (It is the CIL that is executed by the CLR or Common Language Runtime).
String Concatenation Operator
Let's look at a simple example of the use of +=
on a string to start with.
Below is an image from the sharplab.io site. In the left pane is the code I wrote and the right pane shows the lowered code. As you can see, the +=
operator is lowered to use string.Concat
.
Below is the same code but lowered in release mode. Notice how the compiler has eliminated use of the text
variable.
List versus Span Iteration
Let's now look at a more complex example using List and Span.
Below is some code using a List. Notice how the foreach is converted to a while loop using an Enumerator.
Below is similar code using Span. Which do you think will perform faster?
Understanding Records
As an exercise for you, use the site to look at the lowered code for records. Copy the following into the left pane on sharplab.io.
var rec1 = new RecordClass(21, "hello");
// Lowered to use the compiler generated Deconstruct method.
var (num, str) = rec1;
// Lowered to use the compiler generated Clone method.
var rec2 = rec1 with { Num = 42 };
public record RecordClass (int Num, string Str);
When you do you will see all the automatically generated properties and methods you get for free when using records:
- It makes the record class immutable by providing read-only/init properties.
- It generates Equals() and the equals/not equals operators.
- It generates a ToString() implementation.
- It generates a GetHashCode() method so you can use the record in hashing data structures like Dictionary.
- It generates a Descontruct() method used when deconstructing the record.
- It generates a Clone() method which is used in this case when using the
with
keyword.
More Exercises For You to Try
So keep exploring using this tool and see what you can learn. See how the using
statement is lowered. Try some LINQ using the query syntax. Try a switch
statement switching on strings. If you are feeling brave, try async
methods. You can even start exploring the CIL generated to get a sense of the performance of different implementations.