What operator do I overload when assigning an “Enh

2019-06-26 02:51发布

问题:

I need to know, first and foremost, if what I'm trying to do is even possible. If it is possible, I then need to know how.

It's far easier to demonstrate the problem rather than explain it so here goes:

I have an "Enhanced Record" (the purpose - though not important to this question - is to produce a "Smart String" type, to replace the normal String type):

TLKString = record
  Value: String;
  // Some methods here to operate on and build String values

  // Allows me to assign String values directly to "instances" 
  // of this record type! I have others (hence "overload") to 
  // handle other data types (such as Integer etc.)
  class operator Implicit(const AValue: String): TLKString; overload; 
end;

I can now use this TLKString type as follows:

var
  LSmartString: TLKString;
begin
  LSmartString := 'Hello World'; // The "Implicit" operator then 
                                 // assigns this to LSmartString.Value
end;

Okay, so far everything is great! Now we get to the problem...

I need to be able to assign the value of LSmartString (an "instance" of TLKString) to a normal String variable...

var
  LSmartString: TLKString;
  LNormalString: String;
begin
  LSmartString := 'Hello World';

  // The next line works fine, but is not what I want!
  LNormalString := LSmartString.Value; 
  LNormalString := LSmartString; // E2010 (Incompatible Types)
end;

This is where I come unstuck, as (I'm sure you'll notice), the last line of the above snip results in E2010 Incompatible types: 'string' and 'TLKString'. I, of course, knew this would be the case... what I don't know if it's possible to overcome by overloading an operator on my TLKString record type, and if so, what operator I need to overload to do it.

If this isn't possible, then it strikes me as a little silly of CodeGear and Embarcadero to have Implicit and Explicit operators to handle assignment of values to an enhanced Record type, but no operator to handle the inverse.

回答1:

Okay, I've answered this myself... and it was what I would call "blindingly obvious".

Here's the solution (for the benefit of others)

TLKString = record
  Value: String;
  // Some methods here to operate on and build String values
  class operator Implicit(const AValue: String): TLKString; overload; // handles String to TLKString assignment
  class operator Implicit(const AValue: TLKString): String; overload; // handles TLKString to String assignment! THIS IS THE ANSWER!
end;