Spring4D : Setting Null value to Nullable<T> raise error in D12

144 views
Skip to first unread message

RAFILOBERA Andry

unread,
Dec 11, 2023, 5:11:18 AM12/11/23
to Spring4D
Hi all,
Using Spring4D under Delphi 12
    FID : Integer;
    FUpdatedAt     : Nullable<TDateTime>;
    FCreatedAt     : TDateTime;
    FAuthorID      : Nullable<SmallInt>;
    FCurrentUserID : Nullable<SmallInt>;
.....
procedure SomeThing.Init;
begin
  FID            := -1;
  FAuthorID      := Null;
  FCurrentUserID := Null;
  FCreatedAt     := Now;
  FUpdatedAt     := Null;
end;

Assigning FAuthorID or the other Nullable variables to null value rise  exception like this
ThreadId=12880
ProcessId=5
ThreadName=""
ExceptionMessage="Impossible de convertir le variant de type (Null) en type (Integer)"
ExceptionName="EVariantTypeCastError"
ExceptionDisplayName="EVariantTypeCastError"
ExceptionAddress=7545D6C2
FileName=<not available>
LineNumber=<not available>
ExceptionObject=0B7F9250
Classes=[EVariantTypeCastError,EVariantError,Exception,TObject]

This works on D10.4.2.
Tnahks

Stefan Glienke

unread,
Jan 16, 2024, 7:15:01 AMJan 16
to Spring4D
Assigning Null which is a variant to a Nullable<T> is not supported anymore in 2.0 and has been raising warnings in 1.2 for quite some time.
The recommended way is to assign nil.

The reason for this is the behavior of Variants. To assign Null to a Nullable<T> it needed to have an implicit operator overload from Variant to Nullable<T> but this enables assigning any Variant to a nullable.
That might not look harmful at first glance and I also missed its implication until someone showed me this code which compiled but caused a variant cast error at runtime - something that nullable are trying to avoid compared to the rather dynamic variant casting rules:

var n: Nullable<Integer> := 'what?!';

What happens here? Well, because Nullable<T> accepted Variant because of the implicit operator overload the compiler was smart and added a string to variant cast here. So the string gets turned into a variant and that gets passed to the implicit operator overload which then tries to extract an Integer from the Variant which fails.

Piotr Gawlicki

unread,
Apr 28, 2024, 3:59:56 PMApr 28
to Spring4D
Hi all,

When I'm assigned nil to for example TNullableInteger then HasValue is equal to false as expected.
When I have something like Nullable<TObject> then HasValue shows true. Is this expected behavior?
 I'm using Delphi XE2.

Regards. Piotr

Stefan Glienke

unread,
Apr 28, 2024, 4:02:47 PMApr 28
to Spring4D
Nullable is meant for value types - a nullable for reference types makes no sense because a reference type already has the nil state.
When assigning nil to a nullable<T> where T is a type that can be nil then the compiler chooses the overload where you assign a value.
And because of aforementioned reason it does not treat the value nil of the value as no value in context of the nullable.
Reply all
Reply to author
Forward
0 new messages