【问题标题】:Problem with Generic Inheritance (Open Construction)泛型继承问题(开放式构造)
【发布时间】:2009-06-13 14:25:36
【问题描述】:

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

// 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 控制器中创建它(在第 2 级,即在具体类 UserController 之上的类),那么一切都运行良好并且 da.GetUser() 可以作为预计。

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

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

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

感谢任何帮助。

【问题讨论】:

    标签: c# generics inheritance


    【解决方案1】:

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

    【讨论】:

    • 谢谢哥们。错过了那是愚蠢的。我花了 4 个小时进行愚蠢的研究,但没有任何结果。出色的观察力。
    【解决方案2】:

    也许我只是错过了重点,但您应该在层次结构中显式调用基类构造函数。

    这应该可行:

    // 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
       } 
    }
    

    【讨论】:

    • 只要没有参数,就不必显式调用。编译器将插入 :base()
    猜你喜欢
    • 2011-08-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多