Oto skomplikowana (ale może interesująca) alternatywa. Jeśli piszesz coś poważnego, prawdopodobnie powinieneś użyć jednej z sugestii Briana, ale z czystej ciekawości zastanawiałem się, czy można napisać wyrażenie F #, żeby to zrobić. Można zadeklarować typ reprezentujący int
które powinny być używane wyłącznie z kontrolowanych operacji:
type CheckedInt = Ch of int with
static member (+) (Ch a, Ch b) = Checked.(+) a b
static member (*) (Ch a, Ch b) = Checked.(*) a b
static member (+) (Ch a, b) = Checked.(+) a b
static member (*) (Ch a, b) = Checked.(*) a b
Następnie można zdefiniować konstruktora wyrażeń obliczeń (to naprawdę nie jest monada w ogóle, ponieważ typy operacji są całkowicie non-standard):
type CheckedBuilder() =
member x.Bind(v, f) = f (Ch v)
member x.Return(Ch v) = v
let checked = new CheckedBuilder()
po wywołaniu „wiążą” będzie automatycznie owinąć daną wartość całkowitą do liczby całkowitej, które powinny być używane z checked
operacji, więc reszta kodu będzie wykorzystują sprawdzone +
i *
operatorzy zadeklarowane jako członkowie. Kończy się coś takiego:
checked { let! a = 10000
let! b = a * 10000
let! c = b * 21
let! d = c + 47483648 // !
return d }
Zgłasza wyjątek, ponieważ przepełnia się na oznaczonej linii. Jeśli zmienisz numer, zwróci on wartość int
(ponieważ element Return
odwija wartość liczbową od typu Checked
). To trochę szalona technika :-), ale pomyślałem, że może być interesująca!
(Uwaga checked
jest kluczowe zarezerwowana do wykorzystania w przyszłości, więc może wolisz wybrać inną nazwę)
Przeciwnie, jest to możliwe, aby wywołać „zaznaczone” na wszystkich instrukcji w projekcie C#? –
@Heath Hunnicutt - Konwersację można wykonać za pomocą opcji kompilatora, albo w IDE lub w linii poleceń. –