C# List: why you cannot do `List foo = new List();`

前端 未结 9 978
我在风中等你
我在风中等你 2020-12-02 20:05

If you have an Interface IFoo and a class Bar : IFoo, why can you do the following:

List foo = new List();          


        
相关标签:
9条回答
  • 2020-12-02 20:09

    List<Bar> does not inherit from List<IFoo>

    0 讨论(0)
  • 2020-12-02 20:10

    List is the type in this case and it's not an inheritance question List<IFoo> really is different than List<Bar>. List doesn't know anythign of, or inherit the characteristics of either IFoo or Bar.

    Hope that helps.

    0 讨论(0)
  • 2020-12-02 20:11

    If you need to convert a list to a list of a base class or interface you can do this:

    using System.Linq;
    
    ---
    
    List<Bar> bar = new List<Bar>();
    bar.add(new Bar());
    
    List<IFoo> foo = bar.OfType<IFoo>().ToList<IFoo>();
    
    0 讨论(0)
  • 2020-12-02 20:11

    I used some linq to make the conversion easier

    List<Bar> bar = new List<Bar>();
    bar.add(new Bar());
    
    List<IFoo> foo = bar.Select(x => (IFoo)x).ToList();
    

    It is a little less versbose than other answers but works well

    0 讨论(0)
  • 2020-12-02 20:13

    At a casual glance, it appears that this should (as in beer should be free) work. However, a quick sanity check shows us why it can't. Bear in mind that the following code will not compile. It's intended to show why it isn't allowed to, even though it looks alright up until a point.

    public interface IFoo { }
    public class Bar : IFoo { }
    public class Zed : IFoo { }
    
    //.....
    
    List<IFoo> myList = new List<Bar>(); // makes sense so far
    
    myList.Add(new Bar()); // OK, since Bar implements IFoo
    myList.Add(new Zed()); // aaah! Now we see why.
    
    //.....
    

    myList is a List<IFoo>, meaning it can take any instance of IFoo. However, this conflicts with the fact that it was instantiated as List<Bar>. Since having a List<IFoo> means that I could add a new instance of Zed, we can't allow that since the underlying list is actually List<Bar>, which can't accommodate a Zed.

    0 讨论(0)
  • 2020-12-02 20:26

    If you have a list of type List<IFoo> you can call list.add(new Baz()); assuming Baz implements IFoo. However you can't do that with a List<Bar>, so you can't use a List<Bar> everywhere you can use a List<IFoo>.

    However since Bar implements IFoo, you can use a Bar everywhere you use IFoo, so passing a Bar to add works when it expects and IFoo.

    0 讨论(0)
提交回复
热议问题