Nur so eine Idee, die mir gerade kam, aber vielleicht könnte man auch records dafür missbrauchen.
Z.B.:
Delphi-Quellcode:
type
EContractViolation =
class(
Exception)
end;
TObjectNotNil =
record
private
FObj: TObject;
public
operator Implicit(
const Obj: TObject): TObjectNotNil;
operator Implicit(
const Obj: TObjectNotNil): TObject;
end;
operator TObjectNotNil.Implicit(
const Obj: TObject): TObjectNotNil;
begin
if not Assigned(Obj)
then
raise EContractViolation.Create("Reference must
not be nil");
Result.FObj := Obj;
end;
operator TObjectNotNil.Implicit(
const Obj: TObjectNotNil): TObject;
begin
Result := Obj.FObj;
end;
procedure DoSomethingWithObject(Obj: TObjectNotNil);
begin
Obj.
{...}
end;
DoSomethingWithObject(
nil);
// => EContractViolation
Keine Ahnung, ob Delphi das Konstrukt überhaupt zulässt... ich hatte mit dem Implicit-Operator unter Delphi 2006 schon bei harmloseren Sachen Probleme, aber bei 2006 waren überladene record-Operatoren generell buggy.
Und natürlich ist das so, wie es hier steht, viel zu aufgebläht... aber vielleicht könnte man ja irgendwie einen Preprocessor schreiben, der den Code vor der Kompilierung generiert, oder vielleicht kann man mit Generics noch was rausholen.
Wahrscheinlich ist das alles nicht wirklich praktikabel, aber ich wollte die Idee gerade mal niederschreiben...