在开发通过 JSON 与外部数据库通信的类库时,出现了一个有趣的问题,即对象实例的向上转换导致其先前的非空成员之一显示为空。
在试图找出这种奇怪的原因时,许多头发都被扯掉了,但到目前为止,我一直未能找到合理的解释。
这是该问题的一个示例:
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 在向上转换后将实例的先前非空成员视为空?