Zacznijmy dziś od operatora nameof. Zwraca on po prostu nazwę przekazanej metody:
static void Main(string[] args) { string writeLine= nameof(Console.WriteLine); string testFunction = nameof(TestFunction); Console.WriteLine(writeLine); Console.WriteLine(testFunction); } private static string TestFunction(int a,double b) { return null; }
Chyba nie ma tutaj nic nadzwyczajnego. Po prostu zwracana jest nazwa w formie string:
Po co nam to? Na przykład, aby zaimplementować OnPropertyChanged:
public class Person { private string _firstName; public string FirstName { get { return _firstName; } set { _firstName = value; OnPropertyChanged(nameof(FirstName)); } } private void OnPropertyChanged(string propertyName) { // ... } }
Zawsze to lepsze niż atrybuty dodane w .NET 4.5. Generalnie dzięki temu, możemy uniknąć stringow które mogą powodować problemy potem podczas refaktoryzacji.
Odpalmy jeszcze ILSpy i przyjrzyjmy się jak kod wygląda po dekompilacji:
public string FirstName { get { return this._firstName; } set { this._firstName = value; this.OnPropertyChanged("FirstName"); } }
Jak widać, po prostu pierwsza kompilacja (z C# do IL) zastąpiła nameof konkretną nazwą.
Kolejny według mnie bardzo ciekawy operator to tzw. null propagation operator. Załóżmy, że mamy klasę:
class Person { public Address Address { get; set; } } class Address { public string TownName { get; set; } }
W celu wyświetlenia adresu możemy:
Person person = new Person(); Console.WriteLine(person.Address.TownName);
Co jednak gdy address jest NULL? Dostaniemy wyjątek w brzydkim miejscu. Zwykle zaleca się korzystanie z prawa demeter. Czasami jednak jest to dość niewygodne bo kod się trochę komplikuje:
Person person = new Person(); Address address = person.Address; Console.WriteLine(address.TownName);
Za pomocą nowego operatora możemy jednak:
Console.WriteLine(person.Address?.TownName ?? "Brak adresu");
Oczywiście ?. nie sprowadza się wyłącznie tylko do jednej właściwości. Nic nie stoi na przeszkodzie abyśmy napisali:
Person person = null; Console.WriteLine(person?.Address?.TownName ?? "NULL");
Operator zostanie zamieniony na zwykłe ify:
// ConsoleApplication3.Program private static void Main(string[] args) { Person person = null; string arg_1B_0; if (person == null) { arg_1B_0 = null; } else { Address expr_0F = person.Address; arg_1B_0 = ((expr_0F != null) ? expr_0F.TownName : null); } Console.WriteLine(arg_1B_0 ?? "NULL"); }
Jest to kolejne ułatwienie, z którego należy korzystać z umiarkowaniem. Jeśli są to tylko czyste właściwości, wtedy myślę, że można z tego skorzystać. Jeśli wywołujemy jakieś skomplikowane metody, wtedy lepiej rozdzielić kod na kilka linii bo jest to łatwiejsze w debuggowaniu.
Bardzo fajna seria o nowościach w c# 6.0 😉 Pokazane przykłady kodu IL zaciekawiły mnie i fajnie poza tym wiedzieć jak to działa po spodem 🙂