C# 6.0: operator nameof oraz propagacja NULL

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:

image

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.

One thought on “C# 6.0: operator nameof oraz propagacja NULL”

Leave a Reply

Your email address will not be published.