Question

Given the following code:

type
  Class1 = public class
  end;

  Class1Class = class of Class1;

  Class2 = public class (Class1)
  end;

  Class3 = public class (Class1)
  end;

  Class4 = public class
  public
    method DoSomething(c: Class1Class): Integer;
  end;

implementation

method Class4.DoSomething(c: Class1Class): Integer;
begin
  if c = Class2 then
    result := 0
  else if c = Class3 then
    result := 1
  else
    result := 2;
end;

How should DoSomething actually be written, as the equality comparisons throw the compiler error: Type mismatch, cannot find operator to evaluate "class of Class1" = "<type>"

Using is compiles, but in actuality the first conditional always evaluates to true no matter if Class2 or Class3 is passed in.

The goal is to write this in a cross-platform ways without using code specific to any one of the platforms Oxygene supports.

Était-ce utile?

La solution

You must create class references for each class used in the conditionals and use the is operator.

type
  Class1 = public class
  end;

  Class1Class = class of Class1;

  Class2 = public class (Class1)
  end;

  Class3 = public class (Class1)
  end;

  Class4 = public class
  public
    method DoSomething(c: Class1Class): Integer;
  end;

  Class2Class = class of Class2;
  Class3Class = class of Class3;

implementation


method Class4.DoSomething(c: Class1Class): Integer;
begin
  if c is Class2Class then
    result := 0
  else if c is Class3Class then
    result := 1
  else
    result := 2;
end;

Autres conseils

I am not sure why you are testing the class type specifically - ths should not be necessary if you are virtualising the behaviours of the class via the class reference, but assuming you have reasons for needing to work with class identity of a class reference...

You do not say which platform you are working on, but on Java the Java class types work quite well for these purposes, without needing to use Oxygene class references:

method Class4.DoSomething(c: &Class<Object>): Integer;
begin
  case c of
    typeOf(Class2): result := 0;
    typeOf(Class3): result := 1;
  else
    result := 2;
  end;
end;


// Examples of usage:

c4.DoSomething(typeOf(Class1));

someC := new Class3;
c4.DoSomething(someC.Class);

If you are not working on Java or need a platform-portable approach, then you could incorporate an alternate class identity in the classes using virtual class methods:

  Class1 = public class
    class method classID: Integer; virtual;
  end;

Implement this to return some constant identifying Class1. Override in descendant classes to return an appropriate ID for each class. Then in your DoSomething method:

method Class4.DoSomething(c: Class1Class): Integer;
begin
  case c.classID of
    CLASS_2: result := 0;
    CLASS_3: result := 1;
  else
    result := 2;
  end;
end;
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top