C# 为什么可以';接口列表是否使用实现类型?

C# 为什么可以';接口列表是否使用实现类型?,c#,generics,interface,C#,Generics,Interface,接口/泛型一定有一些基本的东西我还没有学会。我希望现在就学会 以下是场景: 我有这个接口和类: public interface IInterface { string TestValue { get; set; } } public class RealValue: IInterface { public string TestValue { get; set; } } 如果我创建一个这样的方法,它编译得很好: public class RandomTest: IMetho

接口/泛型一定有一些基本的东西我还没有学会。我希望现在就学会

以下是场景:

我有这个接口和类:

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 List GetRealValues()
{
List realValues=新列表();

return realValues;//此处出错A
List
不能代替
List
。如果允许,调用者将能够向返回的列表中添加一个
i接口
,该列表的类型不是
RealValue

请注意,如果可以将
List
转换为
List
,则可以调用
.Add(anyObjectImplementingIInterface)
无法工作


但是,您可以使用
.Cast().ToList()

这是因为
列表
是一种特定类型,它不继承
列表
,因此无法转换

但是,在.NET 4.0中,您很幸运。接口
IEnumerable
指定
T
可以是类,也可以是基类,因此您可以将方法更改为:

IEnumerable<IInterface> GetRealValues();
IEnumerable GetRealValues();
请注意,这仅适用于.NET 4.0。因为
IEnumerable
在模板参数上指定了
out
关键字

out
关键字意味着两件事:

  • 在其前面放置
    out
    关键字的类型只能用于类之外的类型。因此,允许使用
    public T MyMethod()
    ,但不允许使用
    public void MyMethod(T myParam)
    ,因为这会进入类

  • 由于这个限制,.NET知道
    T
    可以对从
    T
    继承的所有内容进行大小写。由于这个限制,这保证是一个安全的操作


  • 这看起来很不错。我需要挖掘更多信息来理解
    out
    对于泛型类型参数意味着什么。无论哪种方式,我都尝试过了,并且成功了。用有关
    out
    关键字的更多信息扩展了答案。很好!感谢扩展的答案!
    IEnumerable<IInterface> GetRealValues();