procedure Set_Info(MyObj:TObject; PropName: string; const Value: TValue);
var
  PropKind: TTypeKind;
  Ctx: TRttiContext;
  Field: TRttiField;
begin
  Ctx := TRttiContext.Create;
  try
    Field := Ctx.GetType(MyObj.ClassType).GetField('F' + PropName);
    if Assigned(Field) then Field.SetValue(MyObj, Value)
    else
      raise Exception.Create('Error: Field "PropName + '" not found.');
  finally
    // TRttiContext is a record; no need to free
  end;
end;

procedure Set_Info_NullableDateTime(MyObj:TObject; PropName: string; const Value: TNullable<TDateTime>);
begin
  Set_Info(MyObj, PropName, TValue.From<TNullable<TDateTime>>(Value));
end;

procedure Set_Info_NullableExtended(MyObj:TObject; PropName: string; const Value: TNullable<Extended>);
begin
  Set_Info(MyObj, PropName, TValue.From<TNullable<Extended>>(Value));
end;

procedure Set_Info_NullableInteger(MyObj:TObject; PropName: string; const Value: TNullable<Integer>);
begin
  Set_Info(MyObj, PropName, TValue.From<TNullable<Integer>>(Value));
end;

procedure Set_Info_NullableInt64(MyObj:TObject; PropName: string; const Value: TNullable<Int64>);
begin
  Set_Info(MyObj, PropName, TValue.From<TNullable<Int64>>(Value));
end;

procedure Set_Info_NullableString(MyObj:TObject; PropName: string; const Value: TNullable<string>);
begin
  Set_Info(MyObj, PropName, TValue.From<TNullable<string>>(Value));
end;

procedure Set_Info_NullableVariant(MyObj:TObject; PropName: string; const Value: TNullable<Variant>);
begin
  Set_Info(MyObj, PropName, TValue.From<TNullable<Variant>>(Value));
end;

------------------------

unit pixel_classes;

interface

uses
 System.SysUtils, Rtti, TypInfo;

{$TYPEINFO ON}

type
  TNullValue = record
  end;

  TNullable<T{: record}> = record
  public
    Value: T;
    HasValue: Boolean;

    class operator Implicit(const AValue: T): TNullable<T>;
    class operator Implicit(const AValue: TNullable<T>): T;
    class operator Implicit(const AValue: TNullValue): TNullable<T>;
    class operator Explicit(const AValue: T): TNullable<T>;

    // add these...
    class operator Equal(const A: TNullable<T>; const B: TNullValue): Boolean;
    class operator NotEqual(const A: TNullable<T>; const B: TNullValue): Boolean;
  end;

var NullValue: TNullValue;

implementation

class operator TNullable<T>.Implicit(const AValue: T): TNullable<T>;
begin
  Result.Value := AValue;
  Result.HasValue := True;
end;

class operator TNullable<T>.Implicit(const AValue: TNullable<T>): T;
begin
  if AValue.HasValue then
    Result := AValue.Value
  else
    Result := Default(T); // or raise an exception
end;

class operator TNullable<T>.Implicit(const AValue: TNullValue): TNullable<T>;
begin
  Result.Value := Default(T);
  Result.HasValue := False;
end;

class operator TNullable<T>.Explicit(const AValue: T): TNullable<T>;
begin
  Result.Value := AValue;
  Result.HasValue := True;
end;

class operator TNullable<T>.Equal(const A: TNullable<T>; const B: TNullValue): Boolean;
begin
  Result := not A.HasValue;
end;

class operator TNullable<T>.NotEqual(const A: TNullable<T>; const B: TNullValue): Boolean;
begin
  Result := A.HasValue;
end;

end.

------------------------------

Review the code above and create a complete example of usage for the following class, and create a procedure to populate a generic class, using Rtti and reflection:

type
  TEmployeeProject = class
  private
    FEmployeeID: TNullable<Integer>;
    FDepartmentID: TNullable<Integer>;
    FEmployeeName: TNullable<String>;
    FProjectID: TNullable<Integer>;
    FProjectName: TNullable<String>;
    FProjectBudget: TNullable<Currency>;
    FProjectDate: TNullable<TDateTime>;
    FProjectStartMoment: TNullable<TDateTime>;

  published
    property EmployeeID: TNullable<Integer> read FEmployeeID write FEmployeeID;
    property DepartmentID: TNullable<Integer> read FDepartmentID write FEmployeeID;
    property EmployeeName: TNullable<String> read FEmployeeName write FEmployeeID;
    property ProjectID: TNullable<Integer> read FProjectID write FEmployeeID;
    property ProjectName: TNullable<String> read FProjectName write FEmployeeID;
    property ProjectBudget: TNullable<Currency> read FProjectBudget write FEmployeeID;
    property ProjectDate: TNullable<TDateTime> read FProjectDate write FEmployeeID;
    property ProjectStartMoment: TNullable<TDateTime> read FProjectStartMoment write FEmployeeID;
  end;

  ---------------------------