Kurze Antwort: Geht nicht.
Lange Antwort:
Das Feature, was du hier eigentlich willst, sind Nullable Types.
Glaube ich nicht. Es klingt eher nach nicht-nilbaren Referenztypen (bzw.
non-nullable reference types)
Da wird auch schön erklärt, dass das nachrüsten von denen nicht unter beibehaltung von Kompatibilität möglich ist. Der Speicher für ein neues Objekt muss ja erst alloziert werden. In diesem Moment wird der Speicher mit Nullen gefüllt. Wird der Thread genau danach unterbrochen, kann ein anderer Thread das Objekt beobachten. Referenztypen haben damit standardmäßig den Wert nil (weil eben ein 0x00000000 im Speicher steht) und Wertetypen ebenfalls 0 oder 0.0
Es ist eben kein Zufall, dass das Bitmuster 0x00000000 für alle Typen einen gültigen Wert darstellt.
Design by contract trifft eigentlich schon sehr genau das, was der TE will:
Delphi-Quellcode:
require
aMyReference <> nil;
davor schreiben. Entweder kann der Compiler durch Codeanalyse feststellen, dass der Parameter niemals zu nil werden kann. Oder er wirft einen Fehler und zwingt den Programmierer eine entsprechende Prüfung einzubauen. (Wahrscheinlich im Fall = nil eine
Exception werfen...) Und ja, die Prüfung geschieht bereits zur Compilezeit, soweit möglich. Genau so wie der Compiler ja auch schon ermittelt "Variable x wird ein Wert zugewiesen, aber niemals benutzt" kann er auch nil-Referenzen verfolgen und eine "Vertragsverletzung" feststellen.
Ich finde aber auch die Argumentation schlüssig, dass ein nicht-nilbarer Referenztypen (bzw. non-nullable reference type) nicht viel zur Sprache beiträgt. Gäbe es diesen Typen, müsste sich diese Anforderung ja nach oben hin ausbreiten. Die Variable, die ich hinen stecke, müsste ja genau so nicht-nilbar sein. (Ähnich wie in Java: Ich muss Exceptions entweder fangen oder deklarieren dass die Methode diese werfen kann)
D.h. ich habe den Null-check eben weiter oben in der Hirarchie, aber letztlich nicht gespart.
P.S.: Zusammenfassung aus dem Link oben:
Zitat:
So, long story short: non-nullable reference types is a great idea, but as a practical manner, the objections to implementing it now are enormous. Non-nullability is the sort of thing you want baked into a type system from day one, not something you want to retrofit in 12 years later. Keep that in mind the next time you design a new type system!