我还没有学过关于接口/泛型的基本信息。我希望现在能够学习它。
以下是该方案:
我有这个界面和类:
public interface IInterface
{
string TestValue { get; set; }
}
public class RealValue: IInterface
{
public string TestValue { get; set; }
}
如果我创建一个这样的方法,它编译得很好:
public class RandomTest: IMethodInterface
{
public IInterface GetRealValue()
{
RealValue realValue = new RealValue();
return realValue;
}
}
请注意,我正在返回一个实现接口的对象。
现在,如果我向RandomTest
类添加一个返回列表的方法,那么它就不再起作用了:
public List<IInterface> GetRealValues()
{
List<RealValue> realValues = new List<RealValue>();
return realValues; // ERROR Here <- says it can't convert to a List<IInterface>
}
所以,我的猜测是仿制药无法解决这个问题,但为什么呢?
有解决方法吗?当你实现上述方法的返回值时,你会怎么做?
public interface IMethodInterface
{
IInterface GetRealValue();
List<IInterface> GetRealValues(); // Can't just convert the return types to a concrete
// class because I am implementing this. This
// interface is in a separate project that does not
// have the concrete classes.
}
有希望吗?你会做什么?
答案 0 :(得分:10)
原因是List<RealValue>
是一种特定类型,不会继承List<IInterface>
,因此无法转换。
然而,在.NET 4.0中,你很幸运。接口IEnumerable<out T>
指定T
可以是类或基类,因此您可以将方法更改为:
IEnumerable<IInterface> GetRealValues();
在.NET 4.0上。请注意,这仅适用,因为IEnumerable
在模板参数上指定了out
关键字。
out
关键字意味着两件事:
放置out
关键字之前的类型只能用于类外的类型。因此,public T MyMethod()
是允许的,但不允许public void MyMethod(T myParam)
,因为这会进入课堂;
由于这种限制,.NET知道可以将T
包含在从T
继承的所有内容中。由于这种限制,这可以确保安全操作。
答案 1 :(得分:3)
请注意,如果您可以将List<RealValue>
转换为List<IInterface>
,则可以致电.Add(anyObjectImplementingIInterface)
,但这无效。
但是,您可以使用.Cast<IInterface>().ToList()
。
答案 2 :(得分:1)
不能使用List<RealValue>
代替List<IInterface>
。如果允许,则调用者可以将IInterface
添加到返回的列表中,该列表的类型不是RealValue
。