You can only do that if you declare the interface as having a covariant (out
) parameter. You can only do that if the parameter is used covariantly.
For example, if the interface IMyGenericObject<T>
has a method taking a T
parameter, this prevents you from declaring the parameter as covariant. Conversely, if there is a method that returns a T
, that prevents you from declaring the parameter as contravariant.
EDIT
In response to your comment on SLaks's answer, I'm tempted to repeat everything Eric Lippert has ever written on co- and contravariance. See http://blogs.msdn.com/b/ericlippert/archive/tags/Covariance+and+Contravariance/ and also his answers in SO (most recently https://stackoverflow.com/a/8380213/385844)
To summarize:
You can't cast IList<string>
to IList<object>
because it's legal to pass a FileInfo
to an IList<object>
, but it is not legal to pass it to an IList<string>
.
You can't cast an IList<object>
to an IList<string>
, because it's legal to retrieve an item from an IList<string>
and assign it to a string reference, but an IList<object>
might contain a FileInfo, which can't be assigned to a string reference.
EDIT 2
Since you asked for advice, it's also possible to split your interfaces into co- and contravariant parts. To continue with the list example, you could have these interfaces
public interface ICovariantList<out T>
{
T this[int index] { get; }
//...
}
public interface IContravariantList<in T>
{
T this[int index] { set; }
void Add(T item);
//...
}
public class SomeList<T> : ICovariantList<T>, IContravariantList<T>
{
//...
}
This allows you to use the class covariantly or contravariantly, depending on the context.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…