通用继承问题(开放构造)

时间:2009-06-13 14:25:37

标签: c# generics inheritance

在使用Generic Base Classes时,我遇到了这个奇怪的问题。我有三个级别的基类层次结构,而第四个级别是具体类。如下所示。

// Level 0 (Root Base Class)    
public abstract class BusinessDataControllerBase<BDA> : IBusinessDataController
{
    protected BDA da;
    public BusinessDataControllerBase()
    {
    // Initialize the respective Data Access Layer passed by the concrete class
    BDA da = new BDA();
    }
}


// Level 1 (Second Level Base Class)
public abstract class BusinessRootDataControllerBase<BDA> : BusinessDataControllerBase<BDA>, IBusinessRootDataController
        where BDA : IBusinessDALController, new()
{
}

// Level 2 (Third Level Base Class)
public abstract class BusinessMasterRootDataControllerBase<BRC, BRD, BDA> : BusinessRootDataControllerBase<BDA>, IDisposable
        where BRC : IBusinessRootDataController 
        where BRD : IBusinessRootData
        where BDA : IBusinessDALController, new()
{
}

// Level 3 (Concrete Class)
public class UserController : BusinessMasterRootDataControllerBase<UserController, UserData, UsersDAL>
{
        # region Singleton implementation - Private Constructor, Static initialization
        private static readonly UserController instance = new UserController();
        public static UserController Instance
        {
            get { return instance; }
        }
        # endregion

        # region Constructor
        // --------------------------------------------------------------------------------
        //Private Constuctor
        private UserController()
        {
        }
        // --------------------------------------------------------------------------------

       private void DoLogin(string userName, string password)
        {
            DataSet dstUser = da.GetUser(userName);
            // Check user name
            // Check password
        }
}

我想要达到的目标绝对简单。我需要在顶级基类中实例化'da'对象。具体类型“UsersDAL”由具体类UserController提供,正确的类型应该传播到应该实例化的顶级基类(BusinessDataController)。

现在,当我调试BusinessDataController时,我可以看到正在传播类型(UsersDAL),在BusinessDataControllerBase()构造函数中创建了一个新的UsersDAL()对象,但是一旦代码从构造函数中传出在BusinessDataControllerBase中,'da'成员变量显示为'null',因此DoLogin()进程da.GetUser()发出错误(对象未实例化)。

但是,如果不是在BusinessDataController中实例化'da',而是在BusinessMasterRootData控制器中创建它(在Level 2,即具体类UserController上方的类),那么一切运行正常并且da.GetUser()作为预期

我试图探索泛型的遗传影响(封闭式构造和开放式构造等),但在我的代码中找不到任何偏差。在设计/编译时,我没有收到任何错误,并且使用IntelliSense获取UsersDAL的所有方法,这可能表明类型用法是正确的。

知道我哪里错了吗?我将在第三级有多个基类,即'BusinessMasterRootDataControllerBase'级别。因此,在第三级实例化'da'将使具体类中的'da'可用,但在该级别的所有类中将是多余的,这就是为什么我要将它('da')置于更高的位置。顺便说一句,如果我将构造函数代码放在第二级(即BusinessRootDataControllerBase),则会发生同样的观察。

要分享的另一个信息是我使用UserController(具体类)作为Singleton类。

感谢任何帮助。

2 个答案:

答案 0 :(得分:2)

in

protected BDA da;
public BusinessDataControllerBase()
{
  // Initialize the respective Data Access Layer passed by the concrete class
  BDA da = new BDA();
}

有两个名为'da'的项目,您正在为一个超出范围的局部变量分配一个新的BDA()。它可能看起来像:

protected BDA da;
public BusinessDataControllerBase()
{
  // Initialize the respective Data Access Layer passed by the concrete class
  da = new BDA();
}

答案 1 :(得分:0)

也许我只是忽略了这一点,但你应该在你的层次结构中显式调用基类构造函数。

这应该有效:

// Level 0 (Root Base Class)     
public abstract class BusinessDataControllerBase<BDA> : IBusinessDataController 
{
   protected BDA da;

   public BusinessDataControllerBase()
   {
      // Initialize the respective Data Access Layer passed by the concrete class
      this.da = new BDA();
   } 
}        

// Level 1 (Second Level Base Class) public abstract class 
BusinessRootDataControllerBase<BDA> : BusinessDataControllerBase<BDA>, IBusinessRootDataController
                    where BDA : IBusinessDALController, new() 
{ 
   public BusinessRootDataControllerBase()
      : base() {}     
}

// Level 2 (Third Level Base Class) public abstract class BusinessMasterRootDataControllerBase<BRC, BRD, BDA> : BusinessRootDataControllerBase<BDA>, IDisposable
      where BRC : IBusinessRootDataController 
      where BRD : IBusinessRootData
      where BDA : IBusinessDALController, new() 
{ 
   public BusinessMasterRootDataControllerBase()
      : base() {} 
}

// Level 3 (Concrete Class) public class UserController : BusinessMasterRootDataControllerBase<UserController, UserData, UsersDAL> 
{
   # region Singleton implementation - Private Constructor, Static initialization
   private static readonly UserController instance = new UserController();

   public static UserController Instance
   {
      get { return instance; }
   }
   # endregion

   # region Constructor
   // --------------------------------------------------------------------------------
   //Private Constuctor
   private UserController()
      : base()
   {
   }
   // --------------------------------------------------------------------------------

   private void DoLogin(string userName, string password)
   {
      DataSet dstUser = da.GetUser(userName);
      // Check user name
      // Check password
   } 
}