由于这是我的第一篇StackOverflow帖子,我想简单地说一下 huge ,感谢那些管理网站的人和那些积极向他人提供帮助的人。 StackOverflow是解决C#代码挑战的一个非常有用的资源。
类描述:在MS VisualStudio 2010 C#.NET控制台应用程序中,我有以下基本/派生层次结构:
Entry
- > DirEntry
Entry
- > FileEntry
- > AudioFileEntry
- > OutputFileEntry
......后三者分别是以下基础/派生层次结构中的成员:
Directory
- > AudioDirectory
- > OutputDirectory
......这样:
Directory
有成员public FileEntry[] file_entries;
AudioDirectory
有成员public AudioFileEntry[] file_entries;
OutputDirectory
有成员public OutputFileEntry[] file_entries;
基类Entry
以下列方式声明:
public class Entry : IComparable
{
public string name;
public int entryID;
public int parentID;
//(other code omitted)
}
Directory
也有成员公开DirEntry[] dir_entries;
没有问题,但请注意DirEntry
不会超过Directory
(没有AudioDirEntry
,例如)。
问题: NullReferenceException
尝试从基类file_entries[n]
方法或其他类中读取Directory
内的常见成员当类型为AudioDirectory
或OutputDirectory
时。
没有相关的类,成员或方法是静态的。我尝试使用new
和override
无济于事。试图让file_entries
属性:
public class Directory
{
public virtual FileEntry[] file_entries { get; set; }
}
public class AudioDirectory : Directory
{
public override AudioFileEntry[] file_entries { get; set; }
//(other code omitted)
}
...因错误“... 'app1.AudioDirectory.file_entries': type must be 'app1.FileEntry[]' to match overridden member 'app1.Directory.file_entries'
”
目标:能够在基类file_entries
方法中引用Directory
,无论该对象是哪种派生类型。我的直觉告诉我,我可能忽略了一些简单的事情,因为上面基本上是多态性的全部内容,并且 应该成为一种方法来实现这一点,而不需要求助于新的dynamic
类型
建议?
-Turbine
答案 0 :(得分:3)
您的问题是,当您覆盖属性或方法时,您无法更改签名,即所涉及的类型。您可以使用new修饰符忽略此限制,但您必须非常清楚这意味着什么(稍后将详细介绍)。在您的情况下,您必须避免在子类中隐式定义属性,因为这将在子类中声明一个与基类中的新变量不同的新变量。我的意思是你的代码与此相同:
public class Directory
{
private FileEntry[] _file_entries;
public virtual FileEntry[] file_entries
{
get { return _file_entries; }
set{_file_entries = value;}
}
}
public class AudioDirectory
{
private AudioFileEntry[] _sub_file_entries;
public new AudioFileEntry[] file_entries
{
get { return _sub_file_entries; }
set{_sub_file_entries = value;}
}
}
这意味着当您在AudioDirectory中设置file_entries时,在基类中访问的变量仍为空。
可能的解决方案是:
public class Directory
{
private FileEntry[] _file_entries;
public virtual FileEntry[] file_entries
{
get { return _file_entries; }
set{_file_entries = value;}
}
}
public class AudioDirectory : Directory
{
public new AudioFileEntry[] file_entries
{
get { return (AudioFileEntry[])base.file_entries; }
set { base.file_entries = value; }
}
}
这应该有效,但要小心使用new修饰符强制编译时绑定,这意味着执行的属性取决于声明的变量的类型,而不是实例的实际错误。例如,在下面的代码中,您有一个AudioDirectory实例,但第一次调用file_entries执行AudioDirectory版本,第二次调用Directory目录:
AudioDirectory ad = new AudioDirectory();
Directory d = ad;
FileEntry[] fa = ad.file_entries;
FileEntry[] fb = d.file_entries;
答案 1 :(得分:0)
“'app1.AudioDirectory.file_entries':type必须是'app1.FileEntry []'才能 匹配重写成员'app1.Directory.file_entries'“
表示您需要返回从基类覆盖的相同类型:
public class Directory
{
public virtual FileEntry[] file_entries { get; set; }
}
public class AudioDirectory : Directory
{
public override FileEntry[] file_entries {
get
{
return new AudioFileEntry[] { new AudioFileEntry() };
}
set
{
//(other code omitted)
}
}
}
如果您有其他问题,请提供您的所有代码。