| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169 |
- unit Neon.Core.Nullables;
- interface
- uses
- System.SysUtils, System.Variants, System.Classes, System.Generics.Defaults, System.Rtti,
- System.TypInfo, System.JSON;
- type
- ENullableException = class(Exception);
- {$RTTI EXPLICIT FIELDS([vcPrivate]) METHODS([vcPrivate])}
- Nullable<T> = record
- private
- FValue: T;
- FHasValue: string;
- procedure Clear;
- function GetValueType: PTypeInfo;
- function GetValue: T;
- procedure SetValue(const AValue: T);
- function GetHasValue: Boolean;
- public
- constructor Create(const Value: T); overload;
- constructor Create(const Value: Variant); overload;
- function Equals(const Value: Nullable<T>): Boolean;
- function GetValueOrDefault: T; overload;
- function GetValueOrDefault(const Default: T): T; overload;
- property HasValue: Boolean read GetHasValue;
- function IsNull: Boolean;
- property Value: T read GetValue;
- class operator Implicit(const Value: Nullable<T>): T;
- class operator Implicit(const Value: Nullable<T>): Variant;
- class operator Implicit(const Value: Pointer): Nullable<T>;
- class operator Implicit(const Value: T): Nullable<T>;
- class operator Implicit(const Value: Variant): Nullable<T>;
- class operator Equal(const Left, Right: Nullable<T>): Boolean;
- class operator NotEqual(const Left, Right: Nullable<T>): Boolean;
- end;
- NullString = Nullable<string>;
- NullBoolean = Nullable<Boolean>;
- NullInteger = Nullable<Integer>;
- NullInt64 = Nullable<Int64>;
- NullDouble = Nullable<Double>;
- NullDateTime = Nullable<TDateTime>;
- implementation
- uses
- Neon.Core.Utils;
- { Nullable<T> }
- constructor Nullable<T>.Create(const Value: T);
- var
- a: TValue;
- begin
- FValue := Value;
- FHasValue := DefaultTrueBoolStr;
- end;
- constructor Nullable<T>.Create(const Value: Variant);
- begin
- if not VarIsNull(Value) and not VarIsEmpty(Value) then
- Create(TValue.FromVariant(Value).AsType<T>)
- else
- Clear;
- end;
- procedure Nullable<T>.Clear;
- begin
- FValue := Default(T);
- FHasValue := '';
- end;
- function Nullable<T>.Equals(const Value: Nullable<T>): Boolean;
- begin
- if HasValue and Value.HasValue then
- Result := TEqualityComparer<T>.Default.Equals(Self.Value, Value.Value)
- else
- Result := HasValue = Value.HasValue;
- end;
- function Nullable<T>.GetHasValue: Boolean;
- begin
- Result := FHasValue <> '';
- end;
- function Nullable<T>.GetValueType: PTypeInfo;
- begin
- Result := TypeInfo(T);
- end;
- function Nullable<T>.GetValue: T;
- begin
- if not HasValue then
- raise ENullableException.Create('Nullable type has no value');
- Result := FValue;
- end;
- function Nullable<T>.GetValueOrDefault(const Default: T): T;
- begin
- if HasValue then
- Result := FValue
- else
- Result := Default;
- end;
- function Nullable<T>.GetValueOrDefault: T;
- begin
- Result := GetValueOrDefault(Default(T));
- end;
- class operator Nullable<T>.Implicit(const Value: Nullable<T>): T;
- begin
- Result := Value.Value;
- end;
- class operator Nullable<T>.Implicit(const Value: Nullable<T>): Variant;
- begin
- if Value.HasValue then
- Result := TValue.From<T>(Value.Value).AsVariant
- else
- Result := Null;
- end;
- class operator Nullable<T>.Implicit(const Value: Pointer): Nullable<T>;
- begin
- if Value = nil then
- Result.Clear
- else
- Result := Nullable<T>.Create(T(Value^));
- end;
- class operator Nullable<T>.Implicit(const Value: T): Nullable<T>;
- begin
- Result := Nullable<T>.Create(Value);
- end;
- class operator Nullable<T>.Implicit(const Value: Variant): Nullable<T>;
- begin
- Result := Nullable<T>.Create(Value);
- end;
- function Nullable<T>.IsNull: Boolean;
- begin
- Result := FHasValue = '';
- end;
- class operator Nullable<T>.Equal(const Left, Right: Nullable<T>): Boolean;
- begin
- Result := Left.Equals(Right);
- end;
- class operator Nullable<T>.NotEqual(const Left, Right: Nullable<T>): Boolean;
- begin
- Result := not Left.Equals(Right);
- end;
- procedure Nullable<T>.SetValue(const AValue: T);
- begin
- FValue := AValue;
- FHasValue := DefaultTrueBoolStr;
- end;
- end.
|