【问题标题】:SomeList<T> : List<T> can't be cast as List<T>?SomeList<T> : List<T> 不能转换为 List<T>?
【发布时间】:2011-08-03 03:04:28
【问题描述】:

参见 Main() 中的注释。为什么我不能执行以下操作?

   public class SomeList<T> : List<T>
{
    public SomeList(List<T> existing)
    {
        foreach (var item in existing)
            Add(item);
    }

    public override string ToString()
    {
        return "I'm a better list.";
    }
}

internal interface IReadStuff<T>
{
    List<T> ReadStuff();
}

public class ReaderStrategy<Foo> : IReadStuff<Foo>
{
    public List<Foo> ReadStuff()
    {
        return new List<Foo>();
    }
}

public class Foo {}

public class Main
{
    public Main()
    {
        var reader = new ReaderStrategy<Foo>();

        // This works, but type is List<Foo>, not SomeList<Foo>
        List<Foo> aList = reader.ReadStuff();
        // This does not compile, but is what I want to do:
        SomeList<Foo> aBetterList = reader.ReadStuff();
        // This compiles, but always generates null for aBetterList:
        SomeList<Foo> anotherBetterList = reader.ReadStuff() as SomeList<Foo>;
        // This is funky but works:
        SomeList<Foo> works = new SomeList<Foo>(reader.ReadStuff());
    }
}

我正在努力理解如何使用具有继承类型的泛型。我对上面有需求是因为我想扩展List&lt;T&gt;的功能是一些特殊的方式,例如见SomeList&lt;T&gt; overrides ToString()。但是,我想使用 .Net generic List&lt;T&gt; 保留我的工厂策略。有没有办法让这个工作?

编辑

我添加了一个接受List&lt;T&gt; 并添加到SomeList&lt;T&gt; 的构造函数。这似乎不自然,但有效。这是一项昂贵的操作,尤其是在List&lt;T&gt; 很大的情况下。

我的问题标题不是最好的,我正在努力寻找一个展示更好方法的示例。

【问题讨论】:

  • 除了ToString(),我在List&lt;T&gt; 中看不到任何虚方法,因此从它继承可能通常不是一个好主意。

标签: c# generics inheritance interface


【解决方案1】:

reader.ReadStuff() 返回List&lt;Foo&gt; - 但您试图将其分配给从List&lt;Foo&gt; 继承的SomeList&lt;Foo&gt; 类型的对象。这不起作用,因为 List&lt;Foo&gt; 不是 SomeList&lt;Foo&gt; - 恰恰相反。

想一想 - 从 ReadStuff() 返回一个 List&lt;Foo&gt; 对象是合法的 - 然后你试图访问这个对象上仅在 SomeList&lt;Foo&gt; 上可用的功能 - 这会中断,这就是为什么 OOP 不会不允许你这样做——子类的实例可以用在需要父类实例的地方——但你不能在需要子类的地方使用父类。

回到你的问题标题:SomeList&lt;T&gt;List&lt;T&gt; 不能转换为List&lt;T&gt;?是的,这是可能的,但您正在尝试将 List&lt;T&gt; 转换为 SomeList&lt;T&gt;

【讨论】:

    【解决方案2】:

    SomeList 的所有实例都是 List 的实例。但是,并非所有 List 实例都是 SomeList 的实例。这就是第二个任务正在做的事情。 reader.ReadStuff() 返回一个列表,而不是 SomeList。希望这可以帮助。

    【讨论】:

      【解决方案3】:

      在您的示例中,您没有将SomeList&lt;Foo&gt; 的实例转换为List&lt;Foo&gt;,而是尝试将List&lt;Foo&gt; 转换为SomeList&lt;Foo&gt;。你从不太具体到更具体,这是行不通的。它应该反过来工作。

      【讨论】:

        【解决方案4】:

        更改此代码

         SomeList<Foo> aBetterList = reader.ReadStuff() 
        
         to 
        SomeList<Foo> aBetterList = reader.ReadStuff()  as SomeList<Foo>; 
        
        before using 
            if(aBetterList !=null) {}
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2021-11-26
          • 2019-05-20
          • 2012-02-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-12-02
          相关资源
          最近更新 更多