2013-10-13 10 views
0

Учитывая следующий код:Как вы сравниваете ссылку класса кислорода на классы?

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; 

Как следует DoSomething на самом деле быть написано, как сравнения равенства забросить ошибку компилятора: Type mismatch, cannot find operator to evaluate "class of Class1" = "<type>"

Использование is компилирует, но в действительности первая условная всегда имеет значение true независимо от того, принимается ли Class2 или Class3.

Цель состоит в том, чтобы написать это кросс-платформенными способами без использования трески специфичный для любой из платформ Oxygene.

ответ

0

Вы должны создать ссылки на классы для каждого класса, используемого в условных выражениях, и использовать оператор is.

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; 
0

Я не знаю, почему вы проверяете тип класса специально - тыс не должны быть необходимыми, если вы виртуализацией поведения класса через ссылку на класс, но если у вас есть причины необходимости работать с классом идентичность ссылки класса ...

вы не сказать, какой платформе вы работаете, но на Java типы классов Java работают достаточно хорошо для этих целей без необходимости использовать ссылки класса Oxygene:

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); 

Если вы не работает на Java или нужен платформа портативного подхода, то вы могли бы включать идентичность альтернативного класса в классах с использованием методов виртуального класса:

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

Реализовать для возврата некоторых постоянной идентификации Class1. Переопределите в классах потомков, чтобы вернуть соответствующий идентификатор для каждого класса. Затем в DoSomething метод:

method Class4.DoSomething(c: Class1Class): Integer; 
begin 
    case c.classID of 
    CLASS_2: result := 0; 
    CLASS_3: result := 1; 
    else 
    result := 2; 
    end; 
end; 
+0

Я обновил этот вопрос, чтобы отразить, что я пытаюсь сохранить это кросс-платформенный совместимы. Что касается «почему», это действительно выходит за рамки вопроса. Я предпочитаю отвечать на вопрос (мой собственный, в данном случае), а не говорить «переписать свой код». Практика всегда намного сложнее, чем теория, и я полагаю, что люди могут переписать код самостоятельно. Лично ваше решение кажется немного более неуклюжим и менее элегантным, чем то, что я делаю. Я не могу понять, как это было бы лучше, а не просто другим. – jep

+0

«Почему» редко выходит за рамки. Если то, что вам нужно сделать, может быть достигнуто с помощью виртуализированного поведения в самом классе (кросс-платформенная по своей природе), тогда возможности для таких ошибок могут быть полностью или полностью устранены, а затем вопрос о идентичности класса становится спорным. Опора на идентификатор класса означает, что в любом месте, где ваш код должен изменяться, поведение, основанное на идентификаторе класса, необходимо обновлять каждый раз, когда вы добавляете новый класс, представляя возможность введения ошибок (бездействия) в будущем. Но вы довольны своим подходом, настолько справедливым. :) – Deltics

+0

Ну, место, в которое я столкнулся, было в блоке кода отладки/регистрации, который я запускал. Так что да, вполне счастлив. :) – jep