通用基本类型的重写方法

问题描述 投票:0回答:2

我当前的结构如下:

public class CustomerRepository
{
    // ..

    public virtual Customer LoadCustomer()
    {
        // ...
    }
}

public class OracleCustomerRepository : CustomerRepository
{
    private OracleConnection oracleConnection;

    public OracleCustomerRepository()
    : base(){
        if(this.EnsureIsConnected()){
             // ...
        }
    }

    private bool EnsureIsConnected(){
        // ..
    }

    public override Customer LoadCustomer(){
        // ..
    }
}

这很好,除了以下事实:-对于每个OracleRepository-我必须再次编写方法EnsureIsConnected,我必须再次声明字段OracleConnection等。

我想抽象一下。我的第一个想法是使用Interface,但不能解决重复代码的问题。我的第二个想法是将基类CustomerRepository用作另一个新基类OracleRepository<T>的泛型类型,该基类随后定义了公共例程。

问题是:据我所知,没有办法override这种通用类型的virtual方法,例如CustomerRepository

这就是我认为它将起作用的方式。

public class OracleRepository<T> where T : class{

    public OracleRepository(){
        this.EnsureIsConnected());
    }

    protected OracleConnection oracleConnection;

    protected EnsureIsConnected(){
        // ...
    }
}

public class OracleCustomerRepository : OracleRepository<CustomerRepository>{

    // ..

    // this is not possible, defined in CustomerRepository
    public override Customer LostCustomer(){

    }
}

关于如何处理此问题的任何建议?

c# .net generics inheritance interface
2个回答
1
投票

您可以这样做吗?还是这不是您想要的?

public abstract class CustomerRepository<T>
{
    protected OracleConnection oracleConnection;

    protected bool EnsureIsConnected()
    {
        return true;
    }

    public abstract T LoadCustomer();
}

public class OracleCustomerRepository : CustomerRepository<Customer>
{        
    public OracleCustomerRepository() : base(){
        if(base.EnsureIsConnected()){
             // ...
        }
    }

    public override Customer LoadCustomer(){
        return new Customer();
    }
}

0
投票

我首先想到的是您的抽象似乎有点泄漏。我通常要做的是使用类似方法创建与数据库引擎交互的界面:

public interface IPersistence
{
    void ExecuteOperation(string prodecureName, Dictionary<string, object> parameters);
    T ExecuteSingle(string procedureName, Dictionary<string, object> parameters, Func<IDataReader, T> rowReader);
    List<T> ExecuteMultirow(string procedureName, Dictionary<string, object> parameters, 
Func<IDataReader, T> rowReader);
}

然后在存储库中将其作为依赖项,并从IoC容器中确定要使用的实现。因此,在您的代码中您将拥有:

public class CustomerRepository
{
    private readonly IPersistence persistence;

    public CustomerRepository(IPersistence persistence)
    {
        this.persistence = persistence;
    }

    public virtual Customer LoadCustomer()
    {
        // preparation code
        return this.persistence.ExecuteSingle("some procedure", parameters, r => new Customer((int)r["Id"], (string)r["DisplayName"]));
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.