C # общий состав - PullRequest
       5

C # общий состав

11 голосов
/ 21 июля 2011

У меня есть интерфейс с именем IEditor

public interface IEditor<T> 
    where T: SpecialObject

SpecialObject - абстрактный класс.

Вот моя проблема:

У меня есть класс, который наследуется от SpecialObject, и представление, которое реализует этот IEditor интерфейс

public class View : IEditor<Person>

Теперь я должен проверить, реализует ли View IEditor<SpecialObject>

Boolean isEditor = View is IEditor<SpecialObject>

Но IEditor всегда ложно

Есть ли возможность проверить, является ли View IEditor<SpecialObject>?

Редактировать

У меня есть метод, который вызывается при возникновении события закрытия. Представления, которые передаются этому методу, могут реализовывать IEditor, но они также могут реализовывать другой интерфейс. В примере IView

  void Closing(object sender, MyEventArgs e)
  {
      if(e.Item is IView)
      {
          // DO some closing tasks

          if(e.Item is IEditor<SpecialObject>)          // always false
          {
              // Do some special tasks
              var editor = e.Item as IEditor<SpecialObject>;

              var storedEditObect = editor.StoredObject;

              // more tasks
          }
      } else if(e.Item is ISomeOtherView)
      {}
  }

У меня есть несколько классов, которые называются Person, Address и так далее. Все они наследуются от SpecialObject. В некоторых случаях e.Item наследуется от IEditor или от IEditor Из-за этого я должен привести к своему базовому классу для доступа к полям свойства defaut

Ответы [ 2 ]

11 голосов
/ 21 июля 2011

Создание неуниверсального базового интерфейса.Например:

public interface IEditor {}

public interface IEditor<T> : IEditor ... {}

Затем проверьте IEditor.

10 голосов
/ 21 июля 2011

Ваша проблема - общая дисперсия. Например, IList<MemoryStream> не IList<Stream>.

Начиная с C # 4, вы можете потенциально сделать ваш интерфейс ковариантным следующим образом:

public interface IEditor<out T> where T: SpecialObject

В этот момент IEditor<Person> будет быть IEditor<SpecialObject> - но это будет работать только в том случае, если ваш интерфейс использует T только в позиции "out".

Если это выполнимо для вас, то, вероятно, оно чище по назначению, чем неуниверсальный базовый интерфейс Леппи - но это хорошая альтернатива, когда ковариация не подходит.

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