Kja*_*tan 8 c# types interface list
给出以下类型:
public interface IPrimary{ void doBattle(); }
// an ISecondary "is" an IPrimary
public interface ISecondary : IPrimary { }
// An implementation of ISecondary is also an IPrimary:
internal class SecondaryImpl : ISecondary
{
// Required, since this is an IPrimary
public void doBattle(){ }
}
Run Code Online (Sandbox Code Playgroud)
为什么我不这样做?
List<IPrimary> list = new List<ISecondary>();
Run Code Online (Sandbox Code Playgroud)
这会导致以下编译错误:
参数类型'System.Collections.Generic.List'的参数类型不可分配给参数类型'System.Collections.Generic.List'
我理解错误,我意识到有一些解决方法.我只是没有看到任何明确的原因,为什么不允许这种直接转换.包含在列表中的值ISecondary,应毕竟是(通过扩展)类型的值IPrimary然后被.为什么List<IPrimary>和List<ISecondary>被解释为不相关的类型?
任何人都可以清楚地解释C#以这种方式设计的原因吗?
一个稍微扩展的例子:我在尝试执行类似以下操作时遇到了这个问题:
internal class Program
{
private static void Main(string[] args)
{
// Instance of ISecondary, and by extention, IPrimary:
var mySecondaryInstance = new SecondaryImpl();
// This works as expected:
AcceptImpl(mySecondaryInstance);
// List of instances of ISecondary, which are also,
// by extention, instances of IPrimary:
var myListOfSecondaries = new List<ISecondary> {mySecondaryInstance};
// This, however, does not work (results in a compilation error):
AcceptList(myListOfSecondaries);
}
// Note: IPrimary parameter:
public static void AcceptImpl(IPrimary instance){ }
// Note: List of type IPrimary:
public static void AcceptList(List<IPrimary> list){ }
}
Run Code Online (Sandbox Code Playgroud)
Mat*_*son 10
public class Animal
{
...
}
public class Cat: Animal
{
public void Meow(){...}
}
List<Cat> cats = new List<Cat>();
cats.Add(new Cat());
cats[0].Meow(); // Fine.
List<Animal> animals = cats; // Pretend this compiles.
animals.Add(new Animal()); // Also adds an Animal to the cats list, since animals references cats.
cats[1].Meow(); // cats[1] is an Animal, so this explodes!
Run Code Online (Sandbox Code Playgroud)
这就是原因.
为什么我不这样做?
List<IPrimary> list = new List<ISecondary>();
想象一下,你有一个像这样定义的方法:
public void PopulateList(List<IPrimary> listToPopulate)
{
listToPopulate.Add(new Primary()); // Primary does not implement ISecondary!
}
Run Code Online (Sandbox Code Playgroud)
如果你把它List<ISecondary>作为参数传递会发生什么?
List<ISecondary>无法分配List<IPrimary>的错误是编译器让您摆脱这些麻烦的方法.
class Evil : IPrimary {...}
list.Add(new Evil()); // valid c#, but wouldn't work
Run Code Online (Sandbox Code Playgroud)
它可以保护您免受错误的影响.列表实例(对象)需要辅助实例.并非每个小学都是次要的.然而,期望的是,主要名单可以容纳任何主要名单.如果我们可以将二级列表视为主要列表:坏事.
实际上,数组确实允许这样做 - 如果你弄错的话,它会在运行时出错.
| 归档时间: |
|
| 查看次数: |
5602 次 |
| 最近记录: |