好吧,我在stackoverflow上读了一下这个主题,看了这个&这个,但仍然有点混淆co/contra-variance.
从这里开始
协方差允许在API中替换"更大"(更不具体)类型,其中原始类型仅用于"输出"位置(例如,作为返回值).逆变量允许在API中替换"较小"(更具体)类型,其中原始类型仅用于"输入"位置.
我知道它与类型安全有关.
关于这in/out件事.我可以说in当我需要写它时,我会使用它,out当它只读它时.并且in意味着反方差,out协方差.但从上面的解释......
与此
例如,a
List<Banana>不能被视为List<Fruit>因为list.Add(new Apple())对List有效但不适用于List<Banana>.
所以不应该是,如果我要使用in/我要写入对象,它必须更大更通用.
我知道这个问题已经被问到但仍然很困惑.
我正在尝试将一个列表传递给一个列表的DerivedClass函数BaseClass,但是我得到了错误:
cannot convert from
'System.Collections.Generic.List<ConsoleApplication1.DerivedClass>'
to
'System.Collections.Generic.List<ConsoleApplication1.BaseClass>'
Run Code Online (Sandbox Code Playgroud)
现在我可以把我List<DerivedClass>投入到一个List<BaseClass>,但我不觉得这样做,除非我理解为什么编译器不允许这样做.
我发现的解释只是说它以某种方式违反了类型安全,但我没有看到它.谁能帮我吗?
什么是编译器允许从转换的风险List<DerivedClass>来List<BaseClass>?
这是我的SSCCE:
class Program
{
public static void Main()
{
BaseClass bc = new DerivedClass(); // works fine
List<BaseClass> bcl = new List<DerivedClass>(); // this line has an error
doSomething(new List<DerivedClass>()); // this line has an error
}
public void doSomething(List<BaseClass> bc)
{
// do something with bc
}
}
class BaseClass
{
}
class DerivedClass : BaseClass
{ …Run Code Online (Sandbox Code Playgroud) 这是我的原始主题: C#泛型继承和协方差
在我的只读接口上,我希望继承工作.
public delegate Boolean EnumerateItemsDelegate<out ItemType>(ItemType item);
public interface IReadOnlyCollection<out ItemType>
{
Boolean ContainsItem(ItemType item);
Array CopyToArray();
void EnumerateItems(EnumerateItemsDelegate<ItemType> enumerateDelegate);
UInt32 Count { get; }
UInt32 Capacity { get; }
}
Run Code Online (Sandbox Code Playgroud)
像这样编译除外:-p
这就是我想要的工作:
IReadOnlyCollection<String> s;
IReadOnlyCollection<Object> o = s;
Run Code Online (Sandbox Code Playgroud)