2010-11-03 3 views
1

У меня возникла проблема с преобразованием интерфейса, который уже был реализован в другой класс, который я хочу выполнить с помощью некоторых дополнительных методов.C# - Преобразование интерфейса в альтернативный базовый класс?

public interface ISomeInterface 
{ 
    int Widgets { get; set;} 
} 

public class SomeClassA : ISomeInterface 
{ 
    int Widgets { get; set;} 
} 

public class SomeClassB : ISomeInterface 
{ 
    int Widgets { get; set;} 
    public void DoExtraStuff() {...} 
} 

ISomeInterface someClassA = new SomeClassA(); 

SomeClassB someClassB = (ISomeInterface)someClassA; //InvalidCastException 
someClassB.DoExtraStuff(); //What i'm trying to execute 

Надеется, что это имеет смысл ...

+0

Почему вы пытаетесь вызвать метод в экземпляре, который не имеет этого метода? Экземпляр чего-то не может стать чем-то другим: SomeClassA не SomeClassB, даже если оба реализуют один и тот же интерфейс. – flq

ответ

3

Нет, это не будет работать.

Пусть SomeClassB имеет некоторые дополнительные поля - то, что вы ожидали бы их значения, когда вы пытались преобразовать из ссылки, которые на самом деле относится к экземпляру SomeClassA к SomeClassB?

Объект никогда не меняет свой тип в .NET, и вы не можете ссылаться на несовместимый тип.

Если вам нужен экземпляр SomeClassB, вам нужно будет создать его - возможно, вы могли бы написать конструктор для SomeClassB, который принимает делегат ISomeInterface.

+2

Еще раз ударьте по Скиту! :-) –

+1

вздох ... он должен поститься. ты когда-нибудь спишь Джона? – Hogan

+1

Это не Скит, это реплика на Android, которую он написал о себе. – Skurmedel

0

Вы не можете этого сделать. Вы можете поднять ваш someClassA на базовый интерфейс ISomeInterface, но он остается SomeClassA; вы не можете использовать экземпляр SomeClassA (даже если вы ссылаетесь на него как ISomeInterface) на SomeClassB; они братья и сестры.

1

Это не сработает, вы можете только бросить дерево.

Можно сказать, что

ISomeInterface someClass = (ISomeInterface)someClassA; 

Но вы не можете добраться до someClassB оттуда.

Вы должны иметь someClassB ребенок от someInterface и someClassA дочернего B

Возможно, что вы действительно хотите, чтобы они как реализовать тот же интерфейс (таким образом изменить интерфейс для включения public void DoExtraStuff() {...}

0

If вы хотите запустить этот метод на данных ClassA, вы должны подумать о своей архитектуре. Если ClassA должен запустить метод, который предоставляет ClassB, то они должны оба использовать один и тот же метод либо через интерфейс, либо с базовым классом.

1

Вы можете использовать только класс или интерфейс clas s наследует или реализует.

Так SomeClassA может быть приведен к ISomeInterface, поскольку она вытекает из него, но не SomeClassB потому что, хотя они имеют интерфейс они разные классы (с потенциально очень разным данным).

0

Я понимаю, что интерфейс гарантирует, что ваш класс содержит определенные методы и данные. Однако вы можете расширить этот интерфейс, и ваш класс может включать другие типы данных и методы. Вы не можете ожидать, что C# вытащит соответствующую информацию из вашего класса, которая, возможно, содержит дополнительные данные, а затем отнесет ее к вашему новому объекту, который также может содержать дополнительные данные.