A saját osztályainkat kiegészíthetjük explicit és implicit konverziós operátorokkal, amelyek meg tudják könnyíteni a típusaink használatát. Az implicit konverziós operátorok a kódban nem látszanak. Tipikus ilyen példa, mikor egy long típusú változónak akarunk int értéket átadni:
int valami = 42;
//implicit cast fog történni.
long masik = valami;
Itt az implicit cast azért engedett meg, mert garantáltan nem fog problémát okozni. A long típus nagyobb, ezért gond nélkül tudja tárolni az int típus értékét. Azonban, ha megfordítjuk a konvertálási sorrendet, akkor bizony fordítási hibát kapunk:
long valami = 42;
//hibát fog eredményezni
//int masik = valami;
int masik = (int)valami;
Ebben az esetben azért kötelező explicit módon jelezni, hogy konverzió fog történni, mert a long változó értéke nem garantálható, hogy bele fog férni egy int típusba. Ez a jelzés alapvetően nem a fordítónak szól, hanem a programozónak, hogy legyen tudatában a konverzió következményének.
Ezzel a két rövid példával azt szerettem volna szemléltetni, hogy egy típushoz az implicit operátor definiálását nagyon meg kell gondolni, mert ezzel valamilyen szinten rejtett logikát építünk a programunkba, ami hosszú távon több kárt tud okozni, mint hasznot.
Szintaxis
A többi operátorhoz hasonlóan ezen operátoroknak is statikus elérésűnek kell lennie. A két operátor felépítésében csupán a használt kulcsszóban van eltérés.
public static explicit operator [Cél típus]([Forrás típus] valtozo)
{
//kód
}
public static implicit operator [Cél típus]([Forrás típus] valtozo)
{
//kód
}
Az alábbi példa az implicit és explicit operátorok átdefiniálását és használatát mutatja be egy kezdetleges tört szám típuson:
namespace PeldaCastOperatorok
{
public struct Tort
{
private long _szamlalo;
private long _nevezo;
public Tort(long szamlalo, long nevezo)
{
_szamlalo = szamlalo;
_nevezo = nevezo;
}
public static implicit operator Tort(int bemenet)
{
return new Tort(bemenet, 1);
}
public static explicit operator decimal(Tort bemenet)
{
return (decimal)bemenet._szamlalo / bemenet._nevezo;
}
}
}
A tesztelő főprogram:
using System;
namespace PeldaCastOperatorok
{
class Program
{
static void Main(string[] args)
{
//implicit cast int-ről long-ra majd Tort-re
Tort pelda = 12;
var pelda2 = new Tort(3, 4);
//Explicit cast
var eredmeny = (decimal)pelda2;
Console.WriteLine(eredmeny);
Console.ReadKey();
}
}
}
A program kimenete:
0,75