C#基本多态性问题

时间:2009-07-31 15:29:16

标签: c# polymorphism class-design

我不确定它真的是一个“多态”问题,但无论如何...... 所以我有一个抽象类和另外两个继承它的类。

基类中的某些代码具有一个变量,该变量在扩展基类的类之间会有所不同。

最好的方法是什么?覆盖“获取”方法?稍微更改架构以调用从base classe到传递值的扩展类的函数...

这是一个例子(它不会编译,只是我如何做的一个小例子):

public abstract class BaseAbstract class {

  ... some code ....

  // Here "listName" would change depending on the extending class
  protected List<Items> getAllItems(String listName) {

    Web.getList(listName);

    ... some code ...

  }

  protected abstract List<Items> getAllItems();

}

public class NewClass : BaseAbstract {
 protected override void getAllItems() {
    return getAllItems("ListNameOfNewClass");
 }
}

我就是这样做的,但是IMO的维护并不是很清楚和容易。

欢迎任何想法或评论!

6 个答案:

答案 0 :(得分:7)

我可能选择这样的东西:

public abstract class Base
{
    protected abstract string ListName { get; }
    public List<Item> GetItems()
    {
        return Web.GetList(ListName);
    }
}

public class Child : Base
{
    protected override string ListName
    {
        get { return "MyListName"; }
    }
}

答案 1 :(得分:4)

Prefer Composition Over Inheritance.

public class Base {
  private ItemListGetter itemListGetter; // assignment/initialization is up to you

  private List<Items> getAllItems() {  // this can now be inlined
    return itemListGetter.getList();
  }

}

如果这是您的子类之间唯一的变异维度,那么这里不再需要继承;只需根据需要建立正确的ItemListGetter。

答案 2 :(得分:2)

我可能会选择以下方法:

public abstract class Base
{
    protected List<Items> getAllItems(String listName) 
    {
        // Implementation
    }

    public abstract List<Items> Items
    {
        get;
    }
}

public class NewClass : Base
{
    public override List<Items> Items
    {
        get
        {
            return base.getAllItems("ListNameOfNewClass");
        }
    }
}

这使得内部受保护的功能(getAllItems)与公开的方法/属性分开,并且还意味着它仍可用于从NewClass继承的任何类。

我已经改变了你的界面并将其作为一个纯粹出于猪头的属性暴露出来!派对,万一你不知道可以做到......

答案 3 :(得分:0)

不确定这是正确答案,但您可以在初始化期间在继承的类中设置基类保护变量吗?

例如:

class test
{
    protected string listName;

    protected void getAllItems() 
    {
        return getAllItems(listName);
    }
}

class test2 : test
{
    public test2()
    {
        base.listName = "MyUniqueList";
    }
}

答案 4 :(得分:0)

我认为实施第三个组件会更有意义:

    public abstract class BaseClass {

        protected abstract IList<Item> getAllItems();
    }

    public class SubClass : BaseClass 
    {
        IItemsProvider itemsProvider;

        protected override IList<Item> getAllItems() 
        {
            return itemsProvider.getAllItems("filter");
        }
    }

    public interface IItemsProvider
    {
        IList<Item> getAllItems(string name);
    }

答案 5 :(得分:0)

如果你真的想继承,那么我会选择ctacke's解决方案。

但一般情况下,您的问题似乎无法通过继承来解决。继承只应用于提供专门的行为。但是,在您的情况下,似乎更多的是配置问题。这意味着您应该提供一个从外部配置的属性(即列表名称),而不需要子类化。