我有以下内容:
class Info
{
public string str;
};
class CarInfo : Info {}
class InfoContainer
{
public virtual List<Info> info_list {get; set;}
public bool is_known(Info inf)
{
if (-1 == info_list.FindIndex( i => i.str == inf.str) return false;
return true;
}
}
class CarFleetInfo : InfoContainer
{
new public List<CarInfo> info_list;
CarFleetInfo()
{
info_list = new List<CarInfo>();
}
}
Main()
{
CarInfo c = new CarInfo();
Info i = new Info();
c.is_known(i);
}
我没有其他“{1}}继承的”特定信息“类(如Info
),以及从CarInfo
继承的几个类,这些类都覆盖InfoContainer
与其他一些“特定信息”的对象列表。
现在,对info_list
的调用引发了一个异常,说c.is_known(i)
为空。
答案 0 :(得分:0)
您的问题是new
上的new public List<CarInfo> info_list;
关键字。在此上下文中,new
表示“忽略我的基类提供的定义(如果有的话),而是使用我自己的定义”。因此,当您设置CarInfo
的{{1}}时,您不设置基础info_list
的{{1}}。然后,当您尝试访问属于Info
的{{1}}时,它为空。
修复它的最好方法就是取出info_list
的{{1}}并简单地使用基类的版本。这是正确的方式,可以执行您在此处尝试执行的操作,但也可以使用其他方法。
答案 1 :(得分:0)
你没有覆盖info_list
属性,你正在影响它。
要覆盖该属性,您应该使用override
关键字而不是new
关键字,然后代码将按预期工作。
当你对属性进行遮蔽时,子类会获得具有相同名称的自己的属性,基类对此一无所知。
答案 2 :(得分:0)
您在一个显式隐藏其基类成员的属性上使用new
。使用override
无效,因为List<Info>
不是List<CarInfo>
。
相反,请考虑使用泛型:
class Info
{
public string Foo { get; set; }
}
class CarInfo : Info {}
class InfoContainer<T>
where T: Info
{
public List<T> info_list { get; set; }
public bool is_known(T inf)
{
if (-1 == info_list.FindIndex(i => i.Foo == inf.Foo)) return false;
return true;
}
}
class CarFleetInfo : InfoContainer<CarInfo>
{
}
答案 3 :(得分:0)
有两个问题:
您无法覆盖具有不同签名的方法
课程信息 { public string str; };
class CarInfo : Info {}
class InfoContainer
{
public virtual List<Info> info_list {get; set;}
public bool is_known(Info inf)
{
if (!info_list.Exists(p => p.str == inf.str)) return false;
return true;
}
}
class CarFleetInfo : InfoContainer
{
public override List<Info> info_list { get; set; }
CarFleetInfo()
{
info_list = new List<Info>();
}
}
您不能公开List<CarInfo>
覆盖公开List<Info>
答案 4 :(得分:0)
我认为您无法将List<CarInfo>
分配给List<Info>
,因此您无法以这种方式覆盖info_list
。要解决此问题,您必须使用泛型类,而不是定义如下:
class InfoContainer<T> where T : Info
{
public virtual List<T> info_list {get; set;}
public bool is_known(T inf)
{
if (-1 == info_list.FindIndex( i => i.str == inf.str) return false;
return true;
}
}
class CarFleetInfo<T> : InfoContainer<T> where T : CarInfo
{
public override List<T> info_list {get;set;}
public CarFleetInfo(){
info_list = new List<T>();
}
}
答案 5 :(得分:-2)
基类的目的是提供将被覆盖的函数和定义。覆盖基类是没有意义的。打破语言可能是一个很好的练习,但一般来说,你在编译器中创建了一个悖论和无限循环。覆盖属性意味着预处理器应该运行代码而不是它的基类操作。
但是,在大多数情况下仍应调用基类操作,以确保实例化并正确初始化继承对象的所有字段和对象。