Code review: operator rzutowania

Rozważmy, następujący kawałek kodu:

struct Color
{
   public static explicit operator Color(short value)
   {
    // jakas tam konwersja - nieistotne dla przykladu
       return new Color {R = value};
   }
   public short R, G, B;
}

Co w nim nie tak? Operatory nie są wspierane przez wszystkie języki. Podczas kompilacji wszystkie operatory zamieniane są na zwykłe metody. Na przykład operator rzutowania implicit zostanie zamieniony na op_Explicit oraz oznaczony  przez CLR specjalnym atrybutem specialname:

.class sequential ansi sealed nested private beforefieldinit Color
   extends [mscorlib]System.ValueType
{
   .method public hidebysig specialname static valuetype Program/Color op_Explicit(int16 'value') cil managed
   {
   }

   .field public int16 B

   .field public int16 G

   .field public int16 R
}

Dobre API musi dostarczać metody, które umożliwiają konwersję za pomocą innych metod niż przeładowane operatory. Dzięki temu, użytkownicy wszystkich języków będą mogli cieszyć się napisanym przez nas API. Warto zatem dostarczyć dodatkowe metody oraz konstruktory, które przyjmują wartości z których można skonstruować dany obiekt:

struct Color
{
   public Color(short value)
   {
       R =G=B= value;
   }
   public static Color FromShort(short value)
   {
       // jakas tam konwersja - nieistotne dla przykladu
       return new Color { R = value,G=value,B=value };   
   }
   public static explicit operator Color(short value)
   {
       return FromShort(value);
   }
   public short R, G, B;
}

Użytkownik zatem może stworzyć Color na podstawie short za pomocą konstruktora, operatora lub statycznej, publicznej funkcji. W C# operator jest najwygodniejszy w użyciu ale i użytkownicy innych języków będą mogli z takiego API korzystać.

Leave a Reply

Your email address will not be published.