2009-06-13 4 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) распространяется, новый объект UsersDAL() создается в конструкторе BusinessDataControllerBase(), но как только код выходит из конструктор в BusinessDataControllerBase, переменные-члены 'da' отображаются как «null», и, следовательно, процесс DoLogin() da.GetUser() дает ошибку (объект не создается).

Но если вместо экземпляра 'da' в BusinessDataController я создаю его в контроллере BusinessMasterRootData (на уровне 2, т.е. класс чуть выше конкретного класса UserController), тогда все работает нормально, а da.GetUser() работает как и ожидалось.

Я попытался исследовать влияние наследования дженериков (закрытая конструкция и открытая конструкция и т. Д.), Но не смог найти отклонений в моем коде. В время проектирования/компиляции я не получаю никакой ошибки и не получаю все методы UsersDAL с IntelliSense, что, возможно, указывает на правильность использования типа.

Любая идея, где я иду не так? У меня будет несколько базовых классов на третьем уровне, то есть уровень «BusinessMasterRootDataControllerBase». Таким образом, создание «да» на третьем уровне сделает «да» доступным в конкретных классах, но будет избыточным во всех классах на этом уровне, и именно поэтому я хочу разместить его («да») выше. Кстати, такое же наблюдение происходит, если я поместил код конструктора на второй уровень (т. Е. BusinessRootDataControllerBase).

Другая информация, которую вы хотите поделиться, я использую UserController (конкретный класс) как класс Singleton.

Любая помощь приветствуется.

ответ

2

в

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

Есть два элемента с именем «да», вы присваиваете новый АРП() к локальной переменной, которая выходит за рамки сразу. Это, вероятно, должно выглядеть следующим образом:

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

Спасибо дружище. Глупо было пропустить это. Мне потребовалось 4 часа глупого исследования без каких-либо результатов. Отличное наблюдение. – Rajarshi

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() –

Смежные вопросы