Как вернуть реализацию интерфейса с интерфейсом в качестве возвращаемого типа? - PullRequest
3 голосов
/ 26 января 2011

У меня есть интерфейс: ISearch<T>, и у меня есть класс, который реализует этот интерфейс: FileSearch : ISearch<FileSearchResult>

У меня есть класс FileSearchArgs : SearchArgs, в котором есть метод для возврата объекта поиска:

public override ISearch<SearchResult> getSearchObject () 
{ 
   return ((ISearch<SearchResult>)new FileSearch()); 
}

Переопределяется с:

public virtual ISearch<SearchResult> getSearchObject () { return null; }

Код будет создаваться только в том случае, если я предоставлю приведение к (ISearch), но он генерирует исключение во время выполнения с невозможностью привести к приведению. Кроме того, предыдущая итерация не применяла универсальные элементы к интерфейсу, поэтому сигнатура метода getSearchObject() была следующей:

public override ISearch getSearchObject() { return new FileSearch();}

Я знаю, что одним из решений могло бы быть возвращение базового класса «Поиск» вместо реализации интерфейса, но я бы предпочел не делать этого и понять, почему я не могу следовать шаблону, который у меня был ранее.

Любая помощь, будет принята с благодарностью. Я пытаюсь значительно упростить происходящее, поэтому, если требуется какое-либо разъяснение, пожалуйста, дайте мне знать!

Заранее спасибо.

1 Ответ

3 голосов
/ 26 января 2011

Попробуйте объявить ваш интерфейс следующим образом:

interface ISearch<out T> { 
  // ...
}

(при условии, что FileSearchResult наследуется от SearchResult и параметр типа встречается только в ковариантных позициях в интерфейсе)

Или, если вы всегда будете использовать SearchResult s 'детей:

interface ISearch<out T> where T : SearchResult { 
  // ...
}

UPDATE

Теперь, когда я знаю, что вы используете параметр типа также в позиции ввода, вы можете использовать базовый неуниверсальный интерфейс:

interface ISearch { }
interface ISearch<T> : ISearch where T : SearchResult { }

// ...

public ISearch getSearchObject() { 
  return new FileSearch(); 
} 

Или отделите ваши интерфейсы (pdf) (если это имеет смысл для вас):

interface ISearchCo<out T> where T : SearchResult {
  T Result { get; }
}
interface ISearchContra<in T> where T : SearchResult {
  T Result { set; }
}

// ...

public ISearchCo<SearchResult> getSearchObject() { 
  return (ISearchCo<SearchResult>)new FileSearch(); 
} 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...