C# 5 attributes on optional parameters
With C# 5, you can put a special attribute on an optional parameter and the compiler will fill in the value not with a constant but with information about the calling method. This means we can implement the Logger.Trace to automagically pick up where it’s being called from:
Now, if the caller calls Log.Trace("some message") the compiler will fill in the missing arguments not with the empty string, but with the file and member where the call happens:
Another example of how you can use this is in implementing INotifyPropertyChanged without needing either literal strings, expression magic or mystic weavers:
public static void Trace(string message, [CallerFilePath] string sourceFile = "", [CallerMemberName] string memberName = "") { string msg = String.Format("{0}: {1}.{2}: {3}", DateTime.Now.ToString("yyyy-mm-dd HH:MM:ss"), Path.GetFileNameWithoutExtension(sourceFile), memberName, message); LoggingInfrastructure.Log(msg); }
Now, if the caller calls Log.Trace("some message") the compiler will fill in the missing arguments not with the empty string, but with the file and member where the call happens:
// In file called Fred.cs public void SomeFunc() { Log.Trace("Hello"); // Compiles to Log.Trace("Hello", "Fred.cs", "SomeFunc") }
Another example of how you can use this is in implementing INotifyPropertyChanged without needing either literal strings, expression magic or mystic weavers:
public class ViewModelBase : INotifyPropertyChanged { protected void SetI grabbed this info from http://www.mindscapehq.com/blog/index.php/2012/03/18/what-else-is-new-in-c-5/. More can be found there, but I thought this feature important/cool enough to blog about it on its own right. And mainly so I don't forget about it...(ref T field, T value, [CallerMemberName] string propertyName = "") { if (!Object.Equals(field, value)) { field = value; OnPropertyChanged(propertyName); } } // usual INPC boilerplate } public class Widget : ViewModelBase { private int _thingy; public int Thingy { get { return _thingy; } set { Set(ref _thingy, value); } // Compiler fills in "Thingy" as propertyName } }