W c# 5.0 dodano dwa nowe atrybuty: CallerMemberName oraz CallerFilePath. Można je stosować do domyślnych parametrów metod:
static private void Print([CallerMemberName]string methodName = null, [CallerFilePath]string fileName = null) { Console.WriteLine(methodName); Console.WriteLine(fileName); }
Wywołanie powyższej metody bez podania argumentów spowoduje przekazaniem nazwy metody, która wywołała Print oraz ścieżki pliku w którym znajduje się ta metoda:
Print();
Jeśli Print został wywołany w metodzie Main wtedy methodName zawiera tekst “Main”.
Jak to jednak może się przydać w praktyce? Pierwsza sprawa to loggery – w łatwy sposób można zapisać nazwę pliku oraz stacktrace. Dla programistów WPF oraz ViewModel jednak warto pokazać pewny przykład, który ułatwia implementacje INotifyPropertyChanged. Jedną z możliwych implementacji w “dawnych” czasach była:
public class ViewModel : INotifyPropertyChanged { private string _text; public string Text { get { return _text; } set { _text = value; OnPropertyChanged("Text"); } } virtual protected void OnPropertyChanged(string propName) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propName)); } } public event PropertyChangedEventHandler PropertyChanged; }
Czasami programiści zamiast przekazywać po prostu string wykorzystywali lambda. W C# 5.0 można jednak wykorzystać wspominany atrybut:
public class ViewModel : INotifyPropertyChanged { private string _text; public string Text { get { return _text; } set { _text = value; RaisePropertyChanged(); } } virtual protected void RaisePropertyChanged([CallerMemberName]string propName=null) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propName)); } } public event PropertyChangedEventHandler PropertyChanged; }
Atrybut spowoduje przekazane do propName tekstu “Text”. Moim zdaniem łatwe i eleganckie – nie trzeba dłużej na sztywno przekazywać stringów albo korzystać z nieco wolniejszej lambdy.
Ciekawy przykład. A atrybuty dodano w .net 4.5 😉
http://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.callermembernameattribute.aspx
Ktory jest dostepny z C# 5.0… 🙂