C # - конвертировать интерфейс в альтернативный базовый класс? - PullRequest
1 голос
/ 04 ноября 2010

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

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  

Надеюсь, это имеет смысл ...

Ответы [ 6 ]

3 голосов
/ 04 ноября 2010

Нет, это не сработает.

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

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

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

1 голос
/ 04 ноября 2010

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

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

1 голос
/ 04 ноября 2010

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

Вы могли бы сказать

ISomeInterface someClass = (ISomeInterface)someClassA; 

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

Вам нужно, чтобы someClassB был дочерним элементом someInterface, а someClassA - дочерним для B

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

0 голосов
/ 04 ноября 2010

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

0 голосов
/ 04 ноября 2010

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

0 голосов
/ 04 ноября 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...