2016-07-14 65 views
0

我正在創建一個數據訪問工廠類。我有一個基本的DataAccess類,它在GetConnection()中返回一個IDBConnection。在SQLDataAccess類中,它基本上返回新的SQLConnection()。我想知道的是如何覆蓋返回類型爲特定的SQLConnection。我知道您無法更改override property with a derived type中討論的方法簽名。但是他們在.net中使用DBConnection.CreateCommand()完成此操作。DBConnection返回一個DBCommand,SQLConnection根據定義返回SQLCommand。他們如何做到這一點?sqlconnection.createCommand如何覆蓋IDBConnection.CreateCommand的返回類型?

回答

1

至於如何SqlConnectionDbConnection派生的其他人做到這一點,他們有一個新的簽名,隱藏在DbConnection上的一個簽名。以下是DbConnection和SqlConnection的部分代碼。

public class abstract DbConnection { 
    // ... 
    public DbCommand CreateCommand() 
    { 
     return this.CreateDbCommand(); 
    } 
    // ... 
} 

public class SqlConnection : DbConnection { 
    // ... 
    public SqlCommand CreateCommand() 
    { 
     return new SqlCommand((string) null, this); 
    } 
    // ... 
} 

您可以使用泛型來實現此目的。還有其他一些方法可以做到這一點,因爲之前已經有過這樣的想法,除此之外,數據庫實現處理各種不同的項目,例如參數,參數類型,可能存在於一個實現中但不是另一箇中的函數的佔位符,所以你的查詢可能不得不根據實現而改變。乍一看(我們顯然沒有在這裏得到整個故事),這似乎是重新發明了輪子,因此研究ORM可能會更好地爲您抽象出大部分內容。

public interface IDataAccess<TConnection, TCommand> where TConnection : IDbConnection where TCommand : IDbCommand 
{ 
    TConnection GetConnection(); 
    TCommand CreateCommand(TConnection connection); 
} 

public class SQLDataAccess : IDataAccess<SqlConnection, SqlCommand> 
{ 
    public SqlConnection GetConnection() 
    { 
     return new SqlConnection(""); 
    } 

    public SqlCommand CreateCommand(SqlConnection connection) 
    { 
     return connection.CreateCommand(); 
    } 
} 

如果你不關心你與那麼我建議你使用的接口工作,忘記了泛型工作的具體實施。示例:

public interface IDataAccess 
{ 
    IDbConnection GetConnection(); 
    IDbCommand CreateCommand(IDbConnection connection); 
} 

public class SQLDataAccess : IDataAccess 
{ 
    public IDbConnection GetConnection() 
    { 
     return new SqlConnection(""); 
    } 

    public IDbCommand CreateCommand(IDbConnection connection) 
    { 
     return connection.CreateCommand(); 
    } 
} 
+0

我正在使用VB.net。他們擁有的最好的就是你可以在繼承類中「隱藏」一種方法..允許這樣做。但是,它實際上並未覆蓋它。因此,如果您有一個DataAccess類型的變量並將其分配給SQLDataAccess的一個實例,那麼當您調用GetConnection時,它將調用DataAccess類中的方法而不調用SQLDataAccess。 – dko

+0

爲了解答您重新發明的評論。是的,我知道我正在重新發明輪子,但是我正在處理古代代碼,並試圖在向後兼容的同時將其現代化。你至少回答了微軟如何做到這一點。現在我想知道如果我去了DBCOnnection con = new SQLConnection(); con.CreateCommand();它會調用哪個CreateCommand方法?從我在vb.net中看到的Shadows。它會調用DBConnection.CreateCommand()方法 – dko

+0

@dko - 我編輯了答案。如果你不在乎認識提供者(一件好事),那麼使用直接的界面。讓所有的東西都引用'IDataAccess'並讓工廠返回正確的實現。您的消費代碼將與IDbConnection,IDbCommand,IDataReader等一起工作。 – Igor

相關問題