【问题标题】:Downcasting from a generic collection of superclass to a sublclass从超类的通用集合向下转换为子类
【发布时间】:2014-10-01 00:40:49
【问题描述】:

考虑以下场景:

public abstract class ClassA
{
    public void SomeMethod();
}

public class ClassB : ClassA
{
    public void MethodForClassB()
    {
    }
}

public class ClassC : ClassA
{
    public void MethodForClassC()
    {
    }
}

public static void Main(string[] args)
{
    var classAList = new List<ClassA>();
    classAList.Add(new ClassB());
    classAList.Add(new ClassC());
}

现在如果我想这样做:

ClassB retrievedClass = List[0];

为了让我可以在 ClassA 的 sublass 上执行方法,编译器强制我向下转换为特定的 sublass 类型:

ClassB retrievedClass = (ClassB) List[0];

所以我的问题如下:

  1. 为什么框架不为我做隐式转换,因为类型是兼容的?
  2. 由于您需要强制转换为特定类型,因此此操作不是一种拆箱吗?
  3. 与来自 Object 的向下转换相比,向下转换的成本是多少?
  4. 是否有更好/更有效的方法来存储/访问共享相同超类的子类。

【问题讨论】:

    标签: c# .net oop generics


    【解决方案1】:

    1. Why won't the framework do an implicit cast for me, since the types are compatible?

    嗯,类型兼容。并非每个ClassA 都是ClassB,因此当您从列表中检索ClassA 时,您需要明确指定要向下转换为ClassB

    2. Isn't this operation a type of unboxing since you need to cast to a specific type?

    嗯,不。您没有在此处进行任何拆箱,因为您从未从 classAList 中检索任何元素。此外,装箱是将值类型(诸如intchar 等的原语)制作为引用类型的行为,这里不会发生这种情况,所以你在这里加倍不拆箱。

    3. What is the cost of the downcast as compared to a downcast from an Object?

    它们的成本可能完全相同,因为 ClassBClassC 都是 ClassAobject 的子类。

    4. Is there a better/more efficient way to store/access subclasses that share the same superclass?

    没有。如果您想存储ClassA 或任何扩展它的列表,那么您现在所做的正是您需要做的。

    【讨论】:

    • 这很有意义,尽管您确定在泛型中使用原语时使用装箱?我很确定泛型的全部意义在于完全避免装箱和拆箱,因为对象存储为其本机类型,无论它们是引用类型还是值类型?
    • @Leon 啊,是的。你说得对。我修改了我的答案。 (我所要做的就是删除那句话。)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-23
    • 2011-12-18
    • 2018-05-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多