我已经创建了一个像这样的可空类型,这是我在 SO 答案中发现的,不记得是哪一个了。
unit NullableType;
interface
uses
System.SysUtils, System.Rtti;
type
TNullable<T> = record
private
FValue: T;
FHasValue: IInterface;
function GetHasValue: Boolean;
function GetValue: T;
procedure SetValue(const AValue: T);
public
constructor Create(AValue: T);
function ToString: string; // <-- add this for easier use!
property HasValue: Boolean read GetHasValue;
property Value: T read GetValue write SetValue;
end;
implementation
constructor TNullable<T>.Create(AValue: T);
begin
SetValue(AValue);
end;
function TNullable<T>.GetHasValue: Boolean;
begin
Result := FHasValue <> nil;
end;
function TNullable<T>.GetValue: T;
begin
if HasValue then
Result := FValue
else
Result := Default(T);
end;
procedure TNullable<T>.SetValue(const AValue: T);
begin
FValue := AValue;
FHasValue := TInterfacedObject.Create;
end;
function TNullable<T>.ToString: string;
begin
if HasValue then
begin
if TypeInfo(T) = TypeInfo(TDateTime) then
Result := DateTimeToStr(PDateTime(@FValue)^)
else if TypeInfo(T) = TypeInfo(TDate) then
Result := DateToStr(PDateTime(@FValue)^)
else if TypeInfo(T) = TypeInfo(TTime) then
Result := TimeToStr(PDateTime(@FValue)^)
else
Result := TValue.From<T>(FValue).ToString;
end
else
Result := 'null';
end;
end.
我的问题是我不知道如何将其设置为空。
例如
var
id : TNullable<integer>;
begin
if Edit1.Text <> '' then
id.Value := StrToInt(Edit1.Text)
else
id.Value := null; // runtime error
这给了我运行时错误
无法将类型 (Null) 的变量转换为类型 (Integer)
我已经有一段时间没有用 Delphi 编程了,我就是搞不清楚如何设置id
变量的值null
id.Value := nil;
给出编译器错误
不兼容的类型:“整数”和“指针”
只有不设置 的值,id
我才能获得它的值null
,但如果我想将其设置为任何值,包括 null ,该怎么办?怎么做?
null
Variant
是类型的constVT_NULL
,这就是为什么您会收到与转换相关的运行时错误Variant
。您想要的nil
是。但是,当 a 不是指针类型时,您不能将 a 赋值
nil
给 a 。因此,要执行所需的操作,您需要更新以接受指针作为输入。T
T
Nullable<T>
T^
从 Delphi 2006 开始,
record
可以重载运算符,因此您无需通过Value
属性接受赋值。您可以重载转换运算符,以便将T
值和T^
指针转换为Nullable<T>
(并转换Nullable<T>
为T
值),然后您就可以将nil
指针分配给Nullable
变量,例如:此外,从 Delphi 10.4 开始,您可以使用自定义管理记录来替换
IInterface
简单的Boolean
,例如:IInterface
基于 Allen Bauer 撰写的一篇旧博客文章IInterface
,该文章早于 CMR 的推出。他甚至在文章中指出,CMR 可以解决他用作解决方法的问题!如果您需要支持旧版本的 Delphi,那么只需
IFDEF
相应地编写代码即可。由于您使用接口来检测它是否具有值,因此我会这样做:
您不能通过赋值来完成此操作(或者您可以 - 声明一个接受指针值但只允许
NIL
作为值的赋值运算符,然后调用SetNull
。如果您尝试分配非NIL
指针,则会引发异常)。