This is Part 4 and most likely the last part of my series, lesser-known features of C#. The previous parts of this series are available here:
- Lesser known C# features – Part 1
- Lesser known C# features – Part 2
- Lesser known C# features – Part 3
NumberStyles
It is fairly common to have a requirement to parse a numeric string which contains currency symbol, trailing spaces, parentheses etc. NumberStyles
enum can help parse the numeric string which has these attributes.
Each numeric type
like int
, decimal
, float
etc have Parse
and TryParse
method overloads which takes the NumberStyles
argument.
This enum is also decorated with Flags
attribute which allows us to combine multiple values of the enum. In addition to this, we can use NumberStyles
in combination with NumberFormatInfo
to provide the culture-specific formatting while parsing the numeric string.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Globalization; | |
namespace NumberStylesExample | |
{ | |
public class Program | |
{ | |
static void Main(string[] args) | |
{ | |
// A Hexadecimal number with trailing and leading white spaces | |
Console.WriteLine(int.Parse(" AbCDeF ", NumberStyles.HexNumber | | |
NumberStyles.AllowLeadingWhite | NumberStyles.AllowTrailingWhite)); | |
// A decimal number with -ve number defined within parentheses | |
Console.WriteLine(Decimal.Parse("(10000.23)", NumberStyles.Float | | |
NumberStyles.AllowParentheses)); | |
// A slightly complex example which shows how NumberStyles can be used | |
// with TryParse method along with NumberFormatInfo. | |
var numberFormatInfo = new NumberFormatInfo(); | |
numberFormatInfo.CurrencyDecimalSeparator = ","; | |
numberFormatInfo.CurrencyGroupSeparator = "."; | |
numberFormatInfo.CurrencySymbol = "£"; | |
Double.TryParse("£120500,56", NumberStyles.Float | NumberStyles.Currency, | |
numberFormatInfo, out var result); | |
Console.WriteLine(result); | |
Console.Read(); | |
} | |
} | |
} |
The output of the above code is:
-10000.23
120500.56
Environment.FailFast
Environment.FailFast
immediately terminates the process and write the message to Windows Application Log. If this method is written in try
/finally
block then Environment.FailFast
will prevent the execution of finally
block.
What is the use case of FastFlow
? As per Microsoft documentation:
CONSIDER terminating the process by calling
System.Environment.FailFast
(.NET Framework 2.0 feature) instead of throwing an exception if your code encounters a situation where it is unsafe for further execution.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
namespace FastFailExample | |
{ | |
public class Program | |
{ | |
static void Main(string[] args) | |
{ | |
try | |
{ | |
// Some user code | |
// . | |
// . | |
Environment.FailFast("End of world. Reboot!!!", | |
new Exception("Application terminated.")); | |
} | |
finally | |
{ | |
Console.WriteLine("This line is never be executed"); | |
} | |
} | |
} | |
} |
Running the above code will immediately terminate the application and log application error in the event log. The finally
block will be not executed.
Here is the Event log error:
namespace alias
- global alias
Let us consider a scenario where we have a member name (e.g class, property, field etc.) with the same name as the namespace in a 3rd party library or a NuGet package we have imported into our project. How can we resolve this conflict in our code? That’s where global
namespace alias can come to our rescue.
Consider a simple example where we have defined a class with the name System
in our assembly.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace GlobalNamespaceAliasExample | |
{ | |
public class System | |
{ | |
public void Log(string message) | |
{ | |
// Code to log | |
} | |
} | |
} |
Now, the System
namespace is also available in .NET Framework. What if we want to use the System
namespace in the same class or in some other class within the same assembly? We can do this by prefixing the member in System
namespace with global
alias as shown below.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace GlobalNameSpaceAliasExample | |
{ | |
public class System | |
{ | |
public void Log(string message) | |
{ | |
global::System.Console.WriteLine(message); | |
} | |
} | |
} |
- Extern alias
Consider another example where two assemblies have the same namespace name. Let us call them Assembly1
and Assembly2
. Each Assembly contains a class with common namespace SameAssemblyName
.
Assembly1
: SameNamespaceName
.Class1
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
namespace SameNamespaceName | |
{ | |
public class Class1 | |
{ | |
public static void MethodA() | |
{ | |
var assemblyame = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name; | |
Console.WriteLine($"Assemble Name: {assemblyame}"); | |
} | |
} | |
} |
Assembly2
: SameNamespaceName
.Class2
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
namespace SameNamespaceName | |
{ | |
public class Class2 | |
{ | |
public static void MethodB() | |
{ | |
var assemblyame = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name; | |
Console.WriteLine($"Assemble Name: {assemblyame}"); | |
} | |
} | |
} |
Now, if our project refers to the above two assemblies then how can we refer to members in each assembly? The answer lies in extern
alias
.
Open solution explorer and select Assembly1
in the References folder of the project which has the two assemblies referred. Next, open the assembly property window by pressing F4
key. Change the alias of Assembly1
from global
to assembly1
as shown in the screenshot below.
You can now add extern alias assembly1
to the top of your class to call Assembly1
with its alias.
Here is the full code:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
extern alias assembly1; | |
namespace NamespaceAliasExample | |
{ | |
public class Program | |
{ | |
static void Main(string[] args) | |
{ | |
assembly1::SameNamespaceName.Class1.MethodA(); | |
SameNamespaceName.Class2.MethodB(); | |
} | |
} | |
} |
The output of the above code is:
Assemble Name: Assembly2
Hope you found tips in this series helpful. Please feel free to share your suggestions and keep the feedback coming 🙂
Leave a Reply