C# 泛型继承问题(开放构造)

C# 泛型继承问题(开放构造),c#,generics,inheritance,C#,Generics,Inheritance,在处理泛型基类时,我遇到了这个奇怪的问题。我有三个级别的基类层次结构,而第四个级别是具体的类。如下所示 // Level 0 (Root Base Class) public abstract class BusinessDataControllerBase<BDA> : IBusinessDataController { protected BDA da; public BusinessDataControllerBase() { // In

在处理泛型基类时,我遇到了这个奇怪的问题。我有三个级别的基类层次结构,而第四个级别是具体的类。如下所示

// 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
        }
}
//级别0(根基类)
公共抽象类BusinessDataControllerBase:IBusinessDataController
{
受保护的BDA-da;
public BusinessDataControllerBase()
{
//初始化具体类传递的相应数据访问层
BDA da=新的BDA();
}
}
//一级(二级基类)
公共抽象类BusinessRootDataControllerBase:BusinessDataControllerBase,IBusinessRootDataController
其中BDA:IBusinessDALController,new()
{
}
//二级(三级基类)
公共抽象类BusinessMasterRootDataControllerBase:BusinessRootDataControllerBase,IDisposable
其中BRC:IBusinessRootData控制器
其中BRD:IBusinessRootData
其中BDA:IBusinessDALController,new()
{
}
//3级(混凝土等级)
公共类UserController:BusinessMasterRootDataControllerBase
{
#区域单例实现-私有构造函数,静态初始化
私有静态只读UserController实例=新UserController();
公共静态UserController实例
{
获取{return instance;}
}
#端区
#区域构造函数
// --------------------------------------------------------------------------------
//私人建筑商
私有用户控制器()
{
}
// --------------------------------------------------------------------------------
私有void DoLogin(字符串用户名、字符串密码)
{
数据集dstUser=da.GetUser(用户名);
//检查用户名
//检查密码
}
}
我想要实现的是绝对简单的。我需要在顶级基类中实例化“da”对象。具体类型“UsersDAL”由具体类UserController提供,正确的类型应传播到顶级基类(BusinessDataController),并在该基类中实例化

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

但是,如果我没有在BusinessDataController中实例化“da”,而是在BusinessMasterRootData controller中创建它(在级别2,即具体类UserController的正上方的类),那么一切都正常运行,da.GetUser()工作正常

我试图探索泛型(封闭结构和开放结构等)的继承影响,但在我的代码中找不到任何偏差。在设计/编译时,我没有得到任何错误,也没有得到所有带有IntelliSense的UsersDAL方法,这可能表明类型用法是正确的

知道我哪里出错了吗?我将在第三级拥有多个基类,即“BusinessMasterRootDataControllerBase”级。因此,在第三级实例化“da”将使“da”在具体类中可用,但在该级的所有类中都是多余的,这就是为什么我想将其(“da”)放在更高的位置。顺便说一下,如果我将构造函数代码放在第二级(即BusinessRootDataControllerBase),同样的情况也会发生

另一个要分享的信息是,我将UserController(具体类)用作一个单例类

非常感谢您的帮助。

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

也许我没有抓住要点,但是您应该显式地调用层次结构中的基类构造函数

这应该起作用:

// 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
   } 
}
//级别0(根基类)
公共抽象类BusinessDataControllerBase:IBusinessDataController
{
受保护的BDA-da;
public BusinessDataControllerBase()
{
//初始化具体类传递的相应数据访问层
this.da=新的BDA();
} 
}        
//级别1(二级基类)公共抽象类
BusinessRootDataControllerBase:BusinessDataControllerBase,IBusinessRootDataController
其中BDA:IBusinessDALController,new()
{ 
public BusinessRootDataControllerBase()
:base(){}
}
//二级(三级基类)公共抽象类BusinessMasterRootDataControllerBase:BusinessRootDataControllerBase,IDisposable
其中BRC:IBusinessRootData控制器
其中BRD:IBusinessRootData
其中BDA:IBusinessDALController,new()
{ 
public BusinessMasterRootDataControllerBase()
:base(){}
}
//三级(具体类)公共类用户控制器:BusinessMasterRootDataControllerBase
{
#区域单例实现-私有构造函数,静态初始化
私有静态只读UserController实例=新UserController();
公共静态UserController实例
{
获取{return instance;}
}
#端区
#区域构造函数
// --------------------------------------------------------------------------------
//私人建筑商
私有用户控制器()
:base()
{
}
// --------------------------------------------------------------------------------
私有void DoLogin(字符串用户名、字符串密码)
{
数据集dstUser=da.GetUser(用户名);
//检查用户名
//检查密码
} 
}

只要没有参数,就不必显式调用它们。公司