2012-06-17 6 views
4

Я думал о том, как решить проблему, которую у меня есть, и я не уверен, будет ли это работать или нет.Явная перегрузка оператора + наследование

Скажем, у нас есть базовый класс называется и 3 подкласса B, C и D.

 A 
     ^
----------------- 
|  |  | 
B  C  D 

Также у нас есть три класса X, Y и Z.

В моей системе объектов типа B, C, D передаются как тип A, и обычно мне приходится преобразовывать объекты типа B, C, D в объекты X, Y или Z (это не бросок, я их вручную конвертирую, так как они совершенно разные).

Поэтому для преобразования типа объекта A в тип X, Y или ZI необходимо сначала проверить подтип, а затем инициализировать объект X, Y или Z с результатом некоторых операций над объектом A в зависимости от подтипа ,

Я думал о перегрузке явной операции наложения из A в X, Y или Z, просто делая тот же процесс, который я делал, когда я их преобразовал, но потом я подумал ... Возможно ли использовать полиморфизм и перегрузить отбрасывать из B, C и D в некотором роде, что, когда я добавляю новый подтип AI, не нужно менять код литья A? (Просто добавьте явную перегрузку броска к новому подтипу)

Надеюсь, у меня есть объяснил себе, извините, если что-то смущает.

Примечание: Я добавлю перегрузку произнесения на X, Y, Z

+0

Итак, у вас есть 'A', но вы знаете, что это на самом деле' B', поэтому вы конвертируете его в 'X'. Это правильно? – svick

+0

Нет, не знаю. Я просто знаю, что это подтип A, и я хочу преобразовать его в X. (И для Y и Z в других ситуациях) –

+0

Я хочу что-то вроде: A mya = new * Подтип A *; X myx = (X) mya; –

ответ

2

Вы можете иметь свой оператор приведения к типу A вызова виртуальной (или абстрактную?) Метод экземпляра вашего A экземпляра и переопределить для каждого подкласса A. X, Y и Z должны основываться на взаимном базовом классе для этого решения, поэтому оператор трансляции может иметь этот базовый класс в качестве результата.

public abstract class A 
{ 
    protected abstract W ConvertToW(); 

    public static explicit operator W(A a) 
    { 
     return a.ConvertToW(); 
    } 
} 

В этом примере W является базовым классом X, Y и Z.

+0

Могу ли я объявить метод виртуальным и статическим (потому что я думаю, что я должен объявить, что оператор перегружен как статический): S –

+0

@ MarioA.CorcheroJiménez У вас не может быть метода, который является как «виртуальным», так и «статическим», иметь смысл. И да, операторы должны быть «статическими». – svick

+0

@ MarioA.CorcheroJiménez: Нет, вы не можете объявить метод виртуальным и статическим, но вы можете объявить статический оператор, вызывающий виртуальный метод. См. Мой обновленный ответ для некоторого минимального примера кода. –

2
abstract class A 
{ 
    public abstract object Convert(); 
} 
class B : A 
{ 
    public override object Convert() 
    { 
     return ConvertToX(); 
    } 
    public X ConvertToX() 
    { 
     return new X(); 
    } 
} 
void SomeMethod() 
{ 
    A o = new B(); 
    var result = (X)o.Convert(); 
} 

Это позволяет иметь строго типизированный результат, когда вы знаете, что класс B (через ConvertToX, так как X Convert() может» t переопределить object Convert()) и object, когда вы только знаете, что это A. Поскольку явные преобразования могут произойти только на основе статического типа используемой вами переменной, на самом деле нет хорошего способа сделать это, используя кастинг, как вы просили.


(@svick отметил главный недостаток в моем предыдущем коде, который находится ниже, которая является то, что вы не можете легко сделать что-нибудь с ним, если вы знаете только объект является A, не A<T>. Я буду держать его здесь в случае, если у вас есть какие-либо использовать для этого :)

interface IConvertible<out T> 
{ 
    T Convert(); 
} 
abstract class A 
{ 
} 
abstract class A<T> : A, IConvertible<T> 
{ 
    public abstract T Convert(); 
    public static explicit operator T(A<T> a) 
    { 
     return a.Convert(); 
    } 
} 
class B : A<X> 
{ 
    public override X Convert() 
    { 
     // TODO implement this 
    } 
} 

И если у вас есть тип, который может быть преобразован в несколько типов, вы можете сделать:

class B : A<X>, IConvertible<Y> 
{ 
    public override X Convert() 
    { 
     throw new NotImplementedException(); 
    } 
    Y IConvertible<Y>.Convert() 
    { 
     throw new NotImplementedException(); 
    } 
} 

Или:

class B : A, IConvertible<X>, IConvertible<Y> 
{ 
    X IConvertible<X>.Convert() 
    { 
     throw new NotImplementedException(); 
    } 
    Y IConvertible<Y>.Convert() 
    { 
     throw new NotImplementedException(); 
    } 
} 
+2

И как бы вы это использовали, если у вас есть переменная типа 'A'? – svick

3

Предполагая, что X, Y и Z вытекают из общего типа Т, объявить абстрактный метод конверсии в

public abstract class A 
{ 
    public abstract T Convert(); 
} 

и переопределить его в B, чтобы вернуть X, в C, чтобы возвращать Y и в D, чтобы вернуть Z. Таким образом, каждый тип отвечает за возврат собственного преобразованного типа, и в A при изменении нового типа нет изменений.

Смежные вопросы