2009-06-13 35 views
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 
    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類。

任何幫助表示讚賞。

回答

2

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

有兩個項目命名爲「大」,你是一個局部變量立即超出範圍分配新BDA()。它可能應該是這樣的:

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

謝謝哥們。錯過了這一點很愚蠢。我花了4個小時的愚蠢研究,沒有任何結果。優秀的觀察。 – Rajarshi 2009-06-13 14:55:57

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 
    } 
} 
+0

只要沒有參數,就不必顯式調用它們。編譯器將插入:base() – 2009-06-13 14:49:30