父类看不到子参数

时间:2019-07-08 14:39:39

标签: c# visual-studio oop asp.net-core architecture

我已对问题进行了更清晰的编辑。老问题在下面。

我有两个具有自己的数据库客户端实现的子类,但仍在相同的父数据库接口(例如存储库模式)下。

class Child1
{
  protected IDB_Child1 DB;
  public void Disconnect()
  {
    DB.disconnect();
  }
}
class Child2
{
  protected IDB_Child2 DB;
  public void Disconnect()
  {
    DB.Disconnect();
  }
}
interface IDB_Child1 : IDB {}
interface IDB_Child2 : IDB {}
interface IDB { void Disconnect() }

这有效:

Child1 c1 = new Child1();
c1.Disconnect(); //OK

很显然,我想将上面的通用功能移至父级,这是非常基本的重构步骤。我愿意:

abstract class Parent
{
  protected IDB DB;
  public void Disconnect()
  {
    DB.Disconnect();
  }
}

class Child1 : Parent
{
  protected IDB_Child1 DB;
}
class Child2 : Parent
{
  protected IDB_Child2 DB;
}

由于某种原因,C#对于此类变量具有自己的作用域,而我无法从父类访问数据库:

Child1 c1 = new Child1();
c1.Disconnect(); // ERROR: DB is null in the parent even though in the c1 it is initialized and visible from child1 class methods.

我如何实现这种基本的OOP功能?

2 个答案:

答案 0 :(得分:1)

您无需在子级中声明DB(您可以通过继承从父级访问一个)。提示您必须使用new关键字,因为它与父DB字段冲突(通常非常糟糕)。

只需删除

  

新的受保护的IDB_Child数据库;

这是一个完整的实现:

public interface IDB
{
    void Bar();
}

abstract class Parent 
{
    protected IDB DB;
    public Parent(IDB database) {
        DB = database;
    }
    public void Foo()
    {
        DB.Bar();
    }
}
class Child : Parent
{
    public Child(IDBImplem database) : base(database) {}
    public void ChildFoo()
    {
        DB.Bar();
    }
}

public class IDBImplem : IDB
{
    public void Bar()
    {
    }
}

答案 1 :(得分:1)

听起来仿制药可以满足您的需求(假设IDB_Child扩展或实现IDB):

abstract class Parent<T>
{
  protected T DB;
  public void Disconnect()
  {
    DB.Disconnect();
  }
}

class Child1 : Parent<IDB_Child1>
{
}
class Child2 : Parent<IDB_Child2>
{
}

您也可以使用访问器代替继承字段:

abstract class Parent
{
  protected IDB DB() {get;}
  public void Disconnect()
  {
    getDB().Disconnect();
  }
}

class Child1 : Parent
{
  protected IDB_Child1 _DB;
  override IDB DB() 
  {  
      get 
      {
          return DB;
      }
  }
}
class Child2 : Parent
{
  protected IDB_Child2 _DB;
  override IDB DB() 
  {  
      get 
      {
          return DB;
      }
  }
}
  

//错误:即使在c1中已初始化DB,并且在child1类方法中可见,它在父目录中也为空

这是因为您在子类中声明了(但未初始化,但没有显示)新的 DB字段。由于父级DB实例对子级可见,因此您无需声明其他实例。