【问题标题】:why casting Base object to derived type reference working?为什么将 Base 对象转换为派生类型引用工作?
【发布时间】:2014-03-27 19:37:24
【问题描述】:

AFAIK,将基类对象强制转换为派生类型引用会引发运行时异常。但在下面的类中,这完全可以正常工作。

public class Node<T>
{
        // Private member-variables
        private T data;
        private NodeList<T> neighbors = null;

        public Node() {}
        public Node(T data) : this(data, null) {}
        public Node(T data, NodeList<T> neighbors)
        {
            this.data = data;
            this.neighbors = neighbors;
        }

        public T Value
        {
            get
            {
                return data;
            }
            set
            {
                data = value;
            }
        }

        protected NodeList<T> Neighbors
        {
            get
            {
                return neighbors;
            }
            set
            {
                neighbors = value;
            }
        }
    }
}   

public class BinaryTreeNode<T> : Node<T>
{
    public BinaryTreeNode() : base() {}
    public BinaryTreeNode(T data) : base(data, null) {}
    public BinaryTreeNode(T data, BinaryTreeNode<T> left, BinaryTreeNode<T> right)
    {
        base.Value = data;
        NodeList<T> children = new NodeList<T>(2);
        children[0] = left;
        children[1] = right;

    base.Neighbors = children;
}

public BinaryTreeNode<T> Left
{
    get
    {
        if (base.Neighbors == null)
            return null;
        else
            return (BinaryTreeNode<T>) base.Neighbors[0];
    }
    set
    {
        if (base.Neighbors == null)
            base.Neighbors = new NodeList<T>(2);

        base.Neighbors[0] = value;
    }
}

这是取自 MSDN 的示例之一的代码 - http://msdn.microsoft.com/en-us/library/ms379572(v=vs.80).aspx

据我了解,在属性 Left

(BinaryTreeNode<T>) base.Neighbors[0]

将(基本)节点转换为(派生)BinartTreeNode。这是如何工作的?

【问题讨论】:

  • base.Neighbors[0].GetType().Name 报告什么?您没有显示任何对象创建(没有 new Node&lt;&gt;new BinaryTreeNode&lt;&gt;),所以我们无法知道这里的实际对象是什么。
  • base.Neighbors[0] 中的项目实际上可能是BinaryTreeNode。显式转换允许您执行此操作,但如果转换在运行时失败,则会引发异常。不能保证在运行时失败,这就是您所暗示的。或者,可能会实现显式转换运算符,从而进一步混淆情况。
  • 它不工作总是。如果基节点不是该类型,则会收到 InvalidCastException。

标签: c# casting


【解决方案1】:

正是因为它有效,我们可以得出结论,有问题的对象实际上是BinaryTreeNode&lt;T&gt;(或它的子类)。对象一旦创建就永远不会改变类型,所以在某个地方(未在您的示例中显示)您正在创建一个BinaryTreeNode&lt;T&gt;,将其存储为邻居(我们所知道的是它是一个Node&lt;T&gt; - 这很好:这是真的说任何BinaryTreeNode&lt;T&gt;Node&lt;T&gt;;类继承意味着“是”),然后再次成功将其转换回来。这是合法的,但如果节点结果不是BinaryTreeNode&lt;T&gt;,则会在运行时失败。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-09-19
    • 2016-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-21
    • 1970-01-01
    相关资源
    最近更新 更多