0

我有以下内容:

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);
}

我几乎没有其他继承自Info(如 CarInfo)的“特定信息”类,以及少数继承自的类InfoContainer,它们都被info_list其他一些“特定信息”的对象列表覆盖。

c.is_known(i)现在,引发异常的调用info_list为空。

4

6 回答 6

0

你的问题是new关键字 on new public List<CarInfo> info_list;。在这种情况下,new意思是“忽略我的基类提供的定义(如果有的话),并改用我自己的定义”。因此,当您设置 a 时CarInfo,您info_list没有设置 base Infoinfo_list然后,当您尝试访问 的info_list那部分时Info,它为空。

修复它的最佳方法是简单地取出CarInfo'sinfo_list并简单地使用基类的版本。这是执行您在此处尝试执行的操作的正确方法,尽管还有其他方法可以使用。

于 2013-08-22T18:02:38.643 回答
0

您不是在覆盖该info_list属性,而是在遮蔽它。

要覆盖该属性,您应该使用override关键字而不是new关键字,然后代码将按预期工作。

当您隐藏属性时,子类将获得它自己的同名属性,而基类对此一无所知。

于 2013-08-22T18:06:25.063 回答
0

您正在使用new从其基类显式隐藏成员的属性。使用它是无效的,override因为 aList<Info>不是 a 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>
{
}
于 2013-08-22T18:08:01.723 回答
0

有两个问题:

  1. 你应该覆盖而不是阴影
  2. 您不能覆盖具有不同签名的方法

    类信息 { 公共字符串 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>

于 2013-08-22T18:09:38.420 回答
0

我认为您不能将 a 分配List<CarInfo>给 a 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>();
  }
}
于 2013-08-22T18:10:59.387 回答
-2

基类的目的是提供将被覆盖的函数和定义。重写基类是没有意义的。可能是打破语言的一个很好的练习,但总的来说,您正在编译器中创建一个悖论和无限循环。override 属性对预处理器意味着您的代码应该优先运行,而不是它的基类操作。

但是,在大多数情况下,您仍然应该调用基类操作,以确保继承对象的所有字段和对象都被实例化并正确初始化。

于 2013-08-22T17:55:22.650 回答