11

我在覆盖来自接口的属性时遇到问题。我有一个实现接口的基类。这个类有大约 10 个子类。在某些情况下,子类应该覆盖来自接口的属性。

我的问题是,我在不知道对象具有什么类型的类的情况下访问该属性,并且该对象总是返回基类属性值而不是覆盖的子类属性值。

示例代码简化:

public interface Inf
{
   string Info
   {
     get;      
   }
}


public class BaseClass : Inf
{

   public string Info
   {
      get { return "Something"; }
   }

}


public class SubClass : BaseClass 
{

   new public string Info
   {
      get { return "Something else"; }
   }

}

在另一个类中,我必须访问该属性,此时我不知道该对象是基类还是子类

List<BaseClass> listBase = new List<BaseClass>();
listBase.Add(new BaseClass());
listBase.Add(new SubClass());

foreach (BaseClass obj in listBase)
{
  Console.WriteLine(obj.Info);
}

输出:

Something
Something

想要的输出:

Something
Something else

((SubClass)obj).Info 会输出“Something else”,但此时我不知道该对象是什么类。(我有大约 10 个不同的子类)。

我是否必须将所有对象都投射到它的真实类中?我在这个列表中得到了大约 100-200 个对象,并围绕 10 个不同的类。或者有没有其他方法可以做到这一点?

任何帮助表示赞赏:)

4

3 回答 3

12

您应该virtual在基类中实现属性,而override不是new在派生类中的实现上。这应该可以解决问题。

目前,唯一Info从接口提供属性实现的类Inf是您的BaseClass. 根据您的代码,编译器认为派生类SubClass引入了同名的新属性,这是合法的。只有当您直接使用类而不是通过接口时,才能访问此类属性。

于 2013-07-12T11:02:51.227 回答
8

您通过“新建”属性打破了链条。您需要覆盖它:

public interface Inf
{
   string Info
   {
     get;      
   }
}

public class BaseClass : Inf
{
   public virtual string Info
   {
      get { return "Something"; }
   }
}

public class SubClass : BaseClass 
{    
   public override string Info
   {
      get { return "Something else"; }
   }
}
于 2013-07-12T11:03:49.927 回答
5

你这样做是错的。执行以下操作:

  • virtual使用关键字声明基类属性
  • override在子类属性声明旁边添加关键字
public class BaseClass : Inf
{
    public virtual string Info
    {
        get { return "Something"; }
    }
}


public class SubClass : BaseClass
{
    public override string Info
    {
        get { return "Something else"; }
    }
}

结果如你所料。

在此处阅读有关覆盖和多态的更多信息:多态(C# 编程指南)

于 2013-07-12T11:02:48.193 回答