I have an interface defined as
public interface IReaderInfo
{
string Displayname {get;}
}
and a class that implements that interface
public class ReaderInfo : IReaderInfo
{
string DisplayName {get;}
}
I then created a function which return List
public List<ReaderInfo> GetReaders
{
var readers = new List<ReaderInfo>();
var Ireaders = someobject.Getreaders();// Returns the list of IReaderInfo.
// Now i would like cast Ireaders as readers and return.
}
How do i cast it?
By using Linq
You have to create a new list with casted items:
Or, if there is a possibility to have incompatible IReaderInfo entries and you only want the actual ReaderInfo objects in the result:
The quick&very-dirty fix is to pass only the objects that actually are ReaderInfo, by using OfType<>. Using Cast<> will fail if any of the objects implements
IReaderInfo
without actually being a ReaderInfoA better solution though would be to change the method's signature to return a
List<IReaderInfo>
, or the more abstractIList<IReaderInfo>
. IfGetReaders
returns a list of interfaces it means it can return any object that implements the interface.Why discard some of them? Why should
GetReaders
decide which objects to use and which to discard when all implement the same interface?For example, methods typically return interfaces when they do intend to return different types, eg mock objects, or handle multiple implementations. By returning
List<ReaderInfo>
you prevent your method from handling valid objectsUPDATE
Versioning is another very strong reason why one shouldn't cast interfaces to concrete types.
Googling for IReaderInfo I found a couple of pages that refer to RFID readers. A ReaderInfo returns the capabilities of a reader, but how do you expose new features for a new reader?
A common way to expose new features without breaking compatibility is to introduce a new class that implement the old interface
IReaderInfo
and place expose new features through a new interface, egIReaderInfo2
. Or the existing class can be extended withIReaderInfo2
. A library can do that because clients are expected to work only through the interfaces, not directly against the concrete classes.Using LINQ: