Reputation: 3127
Since Delphi (sadly) doesn't support nullable types I wanted to try to make my own implementation of them. This is what I've written so far:
unit Nullable;
interface
uses
System.SysUtils, Generics.Collections;
type
Nullable<T> = class
private
FValue: T;
FHasValue: boolean;
function getValue: T;
procedure setValue(const val: T);
public
constructor Create(value: T);
procedure setNull;
property value: T read getValue write setValue;
property hasValue: boolean read FHasValue;
end;
implementation
{ Nullable<T> }
constructor Nullable<T>.Create(value: T);
begin
Fvalue := value;
FHasValue := true;
end;
procedure Nullable<T>.setNull;
begin
FHasValue := false;
end;
procedure Nullable<T>.setValue(const val: T);
begin
FHasValue := true;
FValue := T; //COMPILER ERROR HERE
end;
function Nullable<T>.getValue: T;
begin
if (FHasValue = false) then
raise Exception.Create('There is not a value!');
Result := T;
end;
end.
It seems that I cannot assing the FValue
with a generic value taken from the function. Is there a way to do this?
I wanted do an easy implementation of nullables. I need a setValue
function because I need to assign the FHasValue
to true or false (so I know if the value is "nullable" or not). In the main form I'd call the code like this:
var a: Nullable<integer>;
begin
a := Nullable<integer>.Create(5);
try
a.setNull;
if (not a.hasValue) then
memo1.lines.add('nullo')
else
memo1.lines.add('valore = ' + a.value.toString);
finally
a.Free;
end;
Upvotes: 2
Views: 605
Reputation: 612794
Instead of
FValue := T;
you mean
FValue := val;
You make the same mistake in the setter method, which is fixed in analagous fashion be replacing
Result := T;
with
Result := FValue;
Remember that T
is a type.
There are a number of good implementations of nullable types in existence already, for instance Spring has one. You might draw inspiration from those, or even use one as is.
Upvotes: 5