W języku C # możemy przeciążać niejawny operator konwersji w ten sposób (przykład z MSDN ):
struct Digit
{
/* ... */
public static implicit operator byte(Digit d) // implicit digit to byte conversion operator
{
/* ... */
}
}
W ten sposób możemy mieć typu, niestandardowy typ wartości , magicznie przekształca się w inny (niezwiązany) typ, pozostawiając widownię w oszołomieniu (dopóki nie zaglądają za kulisy i nie widzą ukrytego operatora konwersji).
Nie lubię pozostawiać w osłupieniu nikogo, kto czyta mój kod. Nie sądzę, że wiele osób tak robi.
Pytanie brzmi: jakie są przypadki użycia operatora konwersji typu domyślnego, który nie sprawi, że mój kod będzie trudniejszy do zrozumienia?
Odpowiedzi:
Poleciłbym jedynie niejawne konwersje między typami, które z grubsza przedstawiają te same wartości na różne sposoby. Na przykład:
RGB
,HSL
,HSV
iCMYK
.Meter
vsInch
).Istnieją jednak pewne wytyczne, które wskazują na silne, gdy jest ona nie należy zdefiniować niejawna konwersja:
InvalidCast
wyjątek ( ), nie powinna być niejawna.O(1)
operacją, nie powinna być niejawna.Powiedzmy teraz, że operator konwersji
f: T1 -> T2
nie narusza żadnej z powyższych reguł, a następujące zachowanie zdecydowanie wskazuje, że konwersja może być niejawna:a == b
takf(a) == f(b)
.a != b
takf(a) != f(b)
.a.ToString() == b.ToString()
takf(a).ToString() == f(b).ToString()
.T1
i naT2
.źródło
T1
(implikowane przez==
relację naT1
) zawsze odwzorowują dwie wartości w tej samej klasie równoważnościT2
. Teraz, gdy o tym myślę, wydaje mi się, że pierwsza właściwość powinna być wymagana do niejawnej konwersji.Gdy typy nie są niepowiązane (z programistami). Istnieją (rzadkie) scenariusze, w których masz dwa niepowiązane typy (w odniesieniu do kodu), które są faktycznie powiązane (w odniesieniu do domeny lub rozsądnych programistów).
Na przykład jakiś kod do dopasowania ciągów. Typowym scenariuszem jest dopasowanie dosłownego ciągu znaków. Zamiast wywoływania
IsMatch(input, new Literal("some string"))
, niejawna konwersja pozwala pozbyć się tej ceremonii - szumu w kodzie - i skupić się na dosłowności łańcucha.Większość programistów zobaczy
IsMatch(input, "some string")
i szybko zrozumie, co się dzieje. Sprawia, że Twój kod jest wyraźniejszy w witrynie połączeń. Krótko mówiąc, nieco łatwiej jest zrozumieć, co się dzieje, przy niewielkim koszcie tego, co się dzieje.Teraz możesz argumentować, że zwykłe przeciążenie funkcji, aby zrobić to samo, byłoby lepsze. I to jest. Ale jeśli tego rodzaju rzeczy są wszechobecne, to posiadanie jednej konwersji jest czystsze (mniej kodu, zwiększona spójność) niż wykonywanie stosu przeciążeń funkcji.
I możesz argumentować, że lepiej jest wymagać od programistów jawnego utworzenia typu pośredniego, aby zobaczyli „to, co się naprawdę dzieje”. To jest mniej proste. Osobiście uważam, że dosłowny przykład dopasowania łańcucha jest bardzo jasny na temat „tego, co naprawdę się dzieje” - programista nie musi znać mechaniki tego, jak wszystko się dzieje. Czy wiesz, jak cały Twój kod jest wykonywany przez różne procesory, na których działa Twój kod? Zawsze istnieje linia abstrakcji, w której programiści przestają dbać o to, jak coś działa. Jeśli uważasz, że niejawne kroki konwersji są ważne, nie używaj niejawnej konwersji. Jeśli uważasz, że to tylko ceremonia, aby komputer był szczęśliwy, a programiście lepiej byłoby nie widzieć tego hałasu wszędzie,
źródło