2011-01-25 2 views
3

У меня есть интерфейс: 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

Каковы отношения (если есть) между 'SearchResult' и' SearchResultSummary'? – Jacob

+0

@Jacob - Извините, сократил имена и явно пропустил вытащить одно «резюме». Я исправил его в сообщении. – Brett

+0

Это лучше. Я предполагаю, что 'FileSearchResult' также происходит из' SearchResult'? – Jacob

ответ

3

Try, чтобы объявить вам интерфейс, как это:

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(); 
} 

Или segregate your interfaces (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(); 
} 
+0

@jordao - Я не уверен, что дает мне «выход», но я устанавливаю тип аксессора с помощью T, который дает мне «T», должен быть инвариантным. 'T' является ковариантным' как ошибка, когда я использую 'out' – Brett

+0

@jordao - На самом деле, я уже делаю это, 'где T: SearchResult', просто думал, что это может быть посторонняя информация – Brett

+2

http: //blogs.msdn .com/b/csharpfaq/archive/2010/02/16/covariance-and-contravariance-faq.aspx –

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