Lesser known C# features – Part 1

Posted by

Language C#  has become very powerful and mature over the years. As with any other language, C# also has few features which are used lesser than others. These are useful but often forgotten features. Through a series of blog post, I want to talk to about these lesser known/used features of C#. This is Part 1 of the series.

Debugger Attributes

Debugger attributes help developers to customize output in the debugger window. These attributes are available in the System.Diagnostics namespace.

  • DebuggerDisplay

DebuggerDisplay attribute controls how a  type or member is displayed in the debugger windows. For example, consider the below class with DebuggerDisplay attribute.

When you debug code, you would see a message as shown below:


  • DebuggerBrowsable

DebuggerBrowser attribute can be used to further control how the properties and fields appear in the debugger window. This attribute takes DebuggerBrowserState enum, which defines  states: NeverCollapsed and RootHidden

The debug window output for above code would appear as below:


Other useful attributes available under this namespace are

  • DebuggerHidden
  • DebuggerNonUserCode
  • DebuggerStepperBoundary
  • DebuggerStepThrough
  • ​DebuggerTypeProxy
  • DebuggerVisualizer

You can refer to the System.Diagnostics namespace to know more about these attributes.

CallerInfo Attributes

As the name suggests, these attributes help to track information of a caller. There are three types of CallerInfo attributes available:

  • CallerMemberName – Gives the name of the caller (eg. method or property name).
  •  CallerFilePath –  Gives the fill path at the time of compilation of the source file that contains the caller.
  • CallerLineNumber – Gives the line number at which a method (caller) was called in the source file.

These attributes are available in the System.Runtime.CompilerServices namespace.

Example, consider a class that logs message from the caller. While logging the message, we would like to get additional information about the method name, source line number etc. It is very tedious to pass this information for each message that needs to be logged. Instead, we can use Caller Info attributes to obtain the information.

When we call Logger.Log from Main method, all we need to pass is the log message and rest of the information is obtained through CallerInfo attributes.

The output of above code snippet is:

[Message]: Testing logging inside Main() method; [Source File Path]: DriveLabel:\Full-Source-File-Path\Program.cs; [Source Line Number]: 7; [Caller Member Name]: Main;

CallerMemberInfo attribute is also used with INotifyProperyChanged  interface. This attributes helps you to keep your code clean as you no longer need to explicitly pass the property name that gets change. You can read more about the usage here.

Hope these tips would help you write better code. Stay tuned for more. 🙂

Also, please share any other lesser known C# features you have been using that you would like me to talk about in this series.