c# - 为什么 C# 在向上转换后将实例的先前非 null 成员视为 null?

标签 c# .net inheritance clr

在开发用于通过 JSON 与外部数据库通信的类库时,出现了一个有趣的问题,即对象实例的向上转换导致其先前非 null 成员之一显示为 null。

在试图找出造成这种奇怪现象的原因时,许多头发都被撕掉了,但到目前为止,我一直未能找到合理的解释。

这是问题的一个例子:

using System;
namespace Test
{
    public class Program
    {
        static void Main(string[] args)
        {
            Descendant d = new Descendant();
            d.Attributes.ToString(); // Everything fine here
            Ancestor a = (Ancestor)d;
            a.Attributes.ToString(); // NullPointerException
        }
    }

    class Ancestor
    {
        public interface IAttributes { }
        public IAttributes Attributes;
    }

    class Descendant : Ancestor
    {
        public new DescendantAttributes Attributes;

        public Descendant()
        {
            this.Attributes = new DescendantAttributes();
        }

        public class DescendantAttributes : IAttributes
        {
            public string Name = "";
        }
    }
}

错误消息:System.NullReferenceException 在 D:\Code\c#\Test\Program.cs:line 12 中的 Test.Program.Main(String[] args) 未处理

.NET 版本:4.0

环境:64 位 Windows 2008 R2、Visual Studio 2010

为什么会这样?我的意思是,除非它是一个错误,否则它背后可能有设计原理。什么样的情况会保证 CLR 在升级后将实例的先前非 null 成员视为 null?

最佳答案

当您使用 new 修饰符时,您隐藏了继承的属性。

public new DescendantAttributes Attributes;

查看以下链接 http://msdn.microsoft.com/en-us/library/vstudio/435f1dw2.aspx

When used as a modifier, the new keyword explicitly hides a member that's inherited from a
base class. When you hide an inherited member, the derived version of the member replaces the
base-class version. You can hide members without using the new modifier, but the result is a
warning. If you use new to explicitly hide a member, the modifier suppresses this warning and
documents the fact that the derived version is intended as a replacement.

关于c# - 为什么 C# 在向上转换后将实例的先前非 null 成员视为 null?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16875119/

相关文章:

c# - 转换来自不同时区的时间,包括夏令时

c# - 破译触发事件的控件

javascript - typescript - 如何获取对象类实例?

maven - 在 Maven 中自动激活父插件

c# - 在 GET/POST 上为 ViewModel 填充 SelectList 的最佳方法

c# - 连接: an invalid argument was supplied上Windows XP家庭版的SocketException

.net - 在Visual Studio 2017中显示多个Docker容器的交互式控制台

c# - Microsoft Enterprise Library 有用吗?

c# - 用子类实例化父对象有什么用

c# - 如何从 Xamarin.forms pcl 中的 Url 检索 json 字符串