Home > Blockchain >  Generic method in property write
Generic method in property write

Time:12-16

I came up with the following for an easy to expand "bit bucket":

unit BitBucket;

interface

type TBitBucket = class
private
  class procedure ThrowAway<T>(value: T); static;
public
  class property Integer: Integer write ThrowAway;
  class property String_: String write ThrowAway;
  class property Extended: Extended write ThrowAway;
  class property Boolean: Boolean write ThrowAway;
end;

implementation

class procedure TBitBucket.ThrowAway<T>(value: T);
begin
end;

end.

However, although there's no squiggly underlines in the IDE, it won't compile, with the following errors:

[dcc32 Error] BitBucket.pas(9): E2008 Incompatible types
[dcc32 Error] BitBucket.pas(10): E2008 Incompatible types
[dcc32 Error] BitBucket.pas(11): E2008 Incompatible types
[dcc32 Error] BitBucket.pas(12): E2008 Incompatible types

Is there a trick I'm missing that will make this compile? I've tried specifying the generic type argument to ThrowAway, but that causes even more errors. The obvious alternative is to write a ThrowAway method for every type, but that would quickly lead to a lot of code to do effectively nothing.


For those wondering why, in delphi, you can use a compiler switch to prevent use of functions without assigning their return value for compatibility with older code. With a BitBucket you can say BitBucket.Integer := FunctionThatHasSideEffectsAndReturnsAnInteger(...);, without having to create a new variable. I also think it's just funny.

CodePudding user response:

You are confusing a generic with a variant. You need something like this:

unit BitBucket;

interface

type 
  TBitBucket<T> = class
  private
    class procedure ThrowAway(const Value: T); static;
    class var FVar: T;
  public
    class property MyProperty: T read FVar write ThrowAway;
  end;

implementation

class procedure TBitBucket<T>.ThrowAway(const Value: T);
begin
  FVar := Value;
end;

end.

The type is not decided until runtime when you access it i.e

TBitBucket<Integer>.MyProperty := 2;

CodePudding user response:

This is the shortest solution i could come up with

type TBitBucket = class
  class var ThrowAway: variant;
end;

Usage

type test = class
  procedure Test;
end;


implementation

{ test }

procedure test.Test;
begin
  TBitBucket.ThrowAway := 'AString';
  TBitBucket.ThrowAway := 1;
  TBitBucket.ThrowAway := 1.1234;
  TBitBucket.ThrowAway := true;
end;

Tvalue example

And here a example with TValue instead from system.RTTI allowing to put objects into the bucket

type TBitBucket = class
  class var ThrowAway: Tvalue;
end;

type test = class
  procedure Test;
end;


implementation

{ test }

procedure test.Test;
begin
  TBitBucket.ThrowAway := 'AString';
  TBitBucket.ThrowAway := 1;
  TBitBucket.ThrowAway := 1.1234;
  TBitBucket.ThrowAway := true;
  TBitBucket.ThrowAway := TObject.Create;
end;
  • Related