Lesser known C# features – Part 3

This is Part 3 of my series, lesser-known features of C#. The previous parts of this series are available here:

Before we delve into the features, I would like to talk about one of the feedback I have received for my previous posts. Many readers have pointed out that the features I talked about are .NET framework features. These features are available in other CLR languages and not limited to C#. I would like to clarify that I started this series with language C# in mind. My intention was to just keep the discussion to C# specific features. However, it is just a coincidence that all the features I talked till now are language independent. I have tried to change that in Part 3.

using static

using static has been there for a while now. But, I think this feature has not received enough love it deserves from the developers. using static was introduced in C# 6.0.

As per the Microsoft docs:

The using static directive designates a type whose static members you can access without specifying a type name

Consider the example of Logger class we have been working on in the previous posts. Here is the static Logger class:


using System.Diagnostics;
using System.Runtime.CompilerServices;
namespace staticUsingExample
{
public static class Logger
{
public static void Log(string message,
[CallerFilePath] string sourceFilePath = "",
[CallerLineNumber] int sourceLineNumber = 0,
[CallerMemberName] string callerMemberName = "")
{
Log($"[Message]: {message}; [Source File Path]: {sourceFilePath}; " +
$"[Source Line Number]: {sourceLineNumber}; [Caller Member Name]: {callerMemberName}; ");
}
[Conditional("DEBUG")]
public static void DebugLog(string message, [CallerMemberName] string callerMemberName = "")
{
Log($"[Message]: {message}; [Caller Member Name]: {callerMemberName};");
}
private static void Log(string message)
{
Debug.WriteLine(message);
}
}
}

view raw

Logger.cs

hosted with ❤ by GitHub

The Log method, due to its nature may be called quite a few times from a class. Prior to C# 6.0, we would end up having Logger.Log call number of times in a single class. Instead, you can use using static as below:


using static staticUsingExample.Logger;
namespace staticUsingExample
{
class Program
{
static void Main(string[] args)
{
DebugLog("Member Start");
// Execute method
Log("Testing logging inside Main() method");
DebugLog("Member End");
}
}
}

view raw

Program.cs

hosted with ❤ by GitHub

This helps to make your code cleaner and easier to understand.

However, I would suggest not to go overboard with this. I personally use this feature only in the scenarios where the static method appears to be an extension of a class. This can be subjective and opinion-based.

I have also found using static to be better suited than using extension methods on few occasions. Consider a hypothetical example, you have a helper method that takes string id as an input and validates the parameterid.


namespace staticUsingExample
{
public static class IdValidationHelper
{
public static bool IsValid(string id)
{
bool isValid = false;
// Validate id
return isValid;
}
}
}

Now, let us say you need to call this method across the project. This can potentially make your code-base polluted with a call similar to IdValidationHelper.IsValid(id).

One of the ways you can look to work around this is by using extension methods. This would help you make a call similar to id.IsValid() making your code easier to understand. However, it also means that IsValid method is now available for any type of string even if it is not an id.

Extension Method Issue

This is where using static can come handy. You no longer, need to prefix the method with the class name and at the same point of time, you no longer need to use an extension method in a wrong context.

One may argue that you can still pass a non-id string argument to the helper method. However, I feel it is still better than exposing the method on the type string since, logically, it is not a part of string type like IsEmpty or other similar extension methods.

Evaluating boolean expressions without short-circuit

We have all used operators && and || to evaluate boolean expressions. These operators do a short-circuit evaluation. That is, if the first expression gives a conclusive result then the second expression is not evaluated. Consider this example:


using System;
namespace ShortCircuitExample
{
public class Program
{
static void Main(string[] args)
{
if (IsStoreOpen() && NeedGrocery())
{
Console.WriteLine("Go to store");
}
else
{
Console.WriteLine("Stay at home");
}
Console.Read();
}
private static bool NeedGrocery()
{
Console.WriteLine("Need grocery");
return false;
}
private static bool IsStoreOpen()
{
Console.WriteLine("Is store open");
return false;
}
}
}

view raw

Program.cs

hosted with ❤ by GitHub

The output of the above code is:

Is store open
Stay at home
 
NeedGrocery method is not called because the first expression returns false. Hence, the second expression is not evaluated.
However, what if you want to evaluate second expression irrespective of result of first expression? You can do this by using & and | operators. These operators do a non-short circuit evaluation.
 
Let us change the above code to use& operator instead of &&.


using System;
namespace NonShortCircuitExample
{
public class Program
{
static void Main(string[] args)
{
if (IsStoreOpen() & NeedGrocery())
{
Console.WriteLine("Go to store");
}
else
{
Console.WriteLine("Stay at home");
}
Console.Read();
}
private static bool NeedGrocery()
{
Console.WriteLine("Need grocery");
return false;
}
private static bool IsStoreOpen()
{
Console.WriteLine("Is store open");
return false;
}
}
}

view raw

Program.cs

hosted with ❤ by GitHub

The output of the above code is:

Is store open
Need grocery
Stay at home
 
 I’m not sure of any real-world example of where you would use a non-short circuit operator.  Maybe, while writing unit tests if you need to evaluate both the expressions for code coverage or for some other reason.  Maybe for debugging.  However, it is there in case you need it 🙂
 
As always, I look forward to hearing your feedback.

Posted

in

by

Tags:

Comments

8 responses to “Lesser known C# features – Part 3”

  1. Iain Ballard Avatar
    Iain Ballard

    & and | are bitwise operators, not boolean.

    Like

    1. Ankit Vijay Avatar
      Ankit Vijay

      HI @iainballard:disqus & and | are bit-wise operators when used with integers. But they can also be used as logical operators when used with Booleans. The example shows how these operators can be used for boolean evaluation.

      Refer: https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/statements-expressions-operators/operators

      One may argue that is not the best practice and can lead to potential bugs. But as I said in my post it is available if any dev or team have a compelling use-case for it.

      Like

  2. Orion Edwards Avatar
    Orion Edwards

    I’ve written code using the bitwise & and | with booleans before. I can’t remember the reason, but it was definitely legitimate and I think something like:

    // we’d like to open both files, but so long as we can open one we’re OK
    if(openFirstFile() | openSecondFile()) {
    //at least one file is open so we can do something
    }

    Like

  3. […] View Reddit by vijayankit – View Source […]

    Like

  4. Swanand Avatar
    Swanand

    Great tips Ankit. The only downside I see to the bitwise operators is someone reading your code (who does not know) may think it is a typo 🙂 and revert back to && or ||, thereby defeating the purpose. Maybe a comment would help to explain why you used bitwise operators instead of logical operators in context.

    Like

  5. […] Lesser known C# features – Part 3 […]

    Like

  6. […] Lesser known C# features – Part 3 […]

    Like

Leave a Reply

A WordPress.com Website.