C# and .NET: 4 features you can find useful
More often than not we program, program and program. Here are some features that you may appreciate if you didn’t know them in C# so you can program, program and program. Since the .NET Core and now at this time .NET 5, If you use C# then the standard library must have some of the types here or else I don’t know which language are you using.
From viewing internal members from elsewhere to some enum features and ending in null coalescing operators which reduce the amount of code we need. This article will not improve your coding skills but will improve your knowledge.
View internal members to another assembly:
Let’s say that you have a class in a different assembly, in this case in another library:
namespace ClassLibrary1
{
public class Class1
{
internal string S1 { get; set; }
}
}
My main program has referenced to use the library. However I can’t access the S1 property of Class1 because it is internal to the package. Now it maybe anti-pattern to do that, but here I am demonstrating language functionality. Although this is done when unit testing internal logic from a testing project. The following will not compile in my main program:
var cls = new Class1();
cls.S1 = "Hello world";
The first line would but not the second. The way to solve this is to use an assembly atribute on the internal class like so, above the namespace declaration in the file:
[assembly: InternalsVisibleTo("MainProgram")]
namespace ClassLibrary1
Now the main program will compile. The InternalsVisibleTo is an attribute InternalsVisibleToAttribute whose attribute usage is assembly only :
[AttributeUsage(AttributeTargets.Assembly)]
Another way of accessing this would have been possible using System.Reflection however this does not have any compile safety associated with it and comes with lower performance.
You may say I want only specific classes to be accessed but not others, here is where you can do it on your own or you may use some libraries in the wild.
Note InternalsVisibleTo will expose the entire assembly project to be visible for the other assembly, where you put the InternalsVisibleTo attribute may matter if you want code unity. One way to resolve this issue is to use the AssemblyInfo.cs. This file is regarded by the compiler as having information on all details such as the title, trademark, copyright and more. More information can be found below:
https://docs.microsoft.com/en-us/dotnet/core/migration/assembly-info
Enum with different store type:
You may not know it but C#‘s enums are numeric behind the scenes. By default an enum is an int (Int32). However you can change that to any of the following types:
- byte
- sbyte
- short
- ushort
- uint
- long
- ulong
You may not ever have to do that. However if memory is a concern you can downgrade from int. Profiling the C# code is advised before and after doing that. Now to define an enum with any of the above types then just inherit from the type just like below:
private enum Some : byte {}
Enum extension methods:
Yes you heard it right. Sometimes you want to treat enums as objects and here you can. You can’t add methods to an enum but you can do with extension methods. It is defined like any extension method would:
public static string EnumExtensionMethod(this UserType userType)
{
// Do work
return string.Empty;
}
Null Coalescing operators:
Since C# 8.0
Here is some sugar code where it relieves you of certain repetitions. Look at the following code:
private void DoSomething(dynamic @dynamic)
{
if (@dynamic.x == null)
{
@dynamic.x *= 2;
}
if (@dynamic.y == null)
{
@dynamic.y = @dynamic.x - 1;
}
if (@dynamic.z == null)
{
@dynamic.z = @dynamic.x + @dynamic.y;
}
return dynamic.x + dynamic.z;
}
This has plenty of checking and gets tedious really quickly. It can be done way easier like so:
private int DoSomething(dynamic @dynamic)
{
@dynamic.x ??= 2;
@dynamic.y ??= @dynamic.x - 1;
@dynamic.z ??= @dynamic.x + @dynamic.y;
return dynamic.x + dynamic.z;
}
Note the ??= operator, it translates to: if the left hand side (variable’s value) is null then set the variable to the right hand side. That’s basically it.
Now a relative operator is ?? which can be used for a similar thing when setting other variables like the example below:
string hello = str == null ? "Hello" : str;
// Can be substituted into the following:
string hello = str ?? "Hello";
Conclusion:
More often than not these features can help you in decreasing lines of code and increase clarity.
Thanks for reading this article.