简体   繁体   中英

How to return an implementation of an interface with interface as return type?

I have an interface: ISearch<T> and I have a class which implements this interface: FileSearch : ISearch<FileSearchResult>

I have a class FileSearchArgs : SearchArgs which has a method to return the a search object:

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

This is overridden from:

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

The code would only build if I provided the cast to (ISearch), but it throws an exception at runtime with an unable to cast error. Additionally, a previous iteration did not apply generics to the interface, and thus the method signature of getSearchObject() was as follows:

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

I know one solution could be to return a base class "Search" instead of an implementation of the interface, but I'd prefer not to do this, and understand why I cannot follow the pattern I previously had.

Any help, would be greatly appreciated. I'm trying to greatly simplify what is going on, so if any clarification is needed, please let me know!

Thanks in advance.

Try to declare you interface like this:

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

(assuming that FileSearchResult inherits from SearchResult , and that the type parameter only occurs in covariant positions in the interface)

Or if you'll always use SearchResult s' children:

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

UPDATE :

Now that I know you use the type parameter also in an input position, you could use a base non-generic interface:

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

// ...

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

Or segregate your interfaces (pdf) (if that makes sense for you):

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM