简体   繁体   English

在 C# 中继承函数和属性

[英]Inheriting functions and properties in C#

I have a class named BaseDAL, this is the parent class.我有一个名为 BaseDAL 的类,这是父类。 AuthorDAL class, ReaderDAL will inherit from BaseDAL class. AuthorDAL 类,ReaderDAL 将继承自 BaseDAL 类。 The BaseDAL class has functions loadDataAsync(), insertAsync..., these functions will call a data query function in the DataProvider, this query function has 1 parameter as the name of a procedure. BaseDAL类有函数loadDataAsync()、insertAsync...,这些函数会调用DataProvider中的一个数据查询函数,这个查询函数有1个参数作为过程的名称。 I tried creating a virtual variable zProceduceName and having subclasses overwrite that variable.我尝试创建一个虚拟变量 zProceduceName 并让子类覆盖该变量。 But I realized that if I do that, every time I call the function differently, I will change the value of that variable to the new procedure name.但我意识到,如果我这样做,每次我以不同的方式调用函数时,我都会将该变量的值更改为新的过程名称。 What I need to do:我需要做什么:

  • Modified the functions in BaseDAL so that I don't need to use the zProceduceName variable to pass the procedure修改了 BaseDAL 中的函数,这样我就不需要使用 zProceduceName 变量来传递过程

This is BaseDAL code:这是 BaseDAL 代码:

protected virtual string zProceduceName { get; set; }

    public virtual async Task<DataTable> loadDataAsync()
    {
        return await DataProvider.Instance.executeQueryAsync(zProceduceName);
    }

    public virtual async Task insertAsync(string pzName, string pzAddress, string pzEmail, string pzPhone, CancellationToken pCt)
    {
        await DataProvider.Instance.executeNonQueryAsync(zProceduceName,pCt, new object[] {pzName,pzAddress,pzEmail,pzPhone});
    }

    public virtual async Task updateAsync( int pnID ,string pzName, string pzAddress, string pzEmail, string pzPhone, CancellationToken pCt)
    {
        await DataProvider.Instance.executeNonQueryAsync(zProceduceName, pCt, new object[] {pnID,pzName,pzAddress,pzEmail,pzPhone});
    }

    public virtual async Task deleteAsync( int pnID,CancellationToken pCt)
    {
        await DataProvider.Instance.executeNonQueryAsync(zProceduceName,pCt, new object[] { pnID});
    }

And this is the AuthorDAL code:这是 AuthorDAL 代码:

public override async Task<DataTable> loadDataAsync()
    {
        zProceduceName = "dbo.LoadAuthor";
        await DataProvider.Instance.executeQueryAsync(zProceduceName);
        return await base.loadDataAsync();
    }

    public override async Task insertAsync( string pzName, string pzAddress, string pzEmail, string pzPhone, CancellationToken pCt)
    {
        zProceduceName = "dbo.InsertAuthor @name , @address , @email , @phone";
        await DataProvider.Instance.executeNonQueryAsync(zProceduceName, pCt, new object[] { pzName, pzAddress, pzEmail, pzPhone });
        await base.insertAsync(pzName, pzAddress, pzEmail, pzPhone, pCt);
    }
    
    public override async Task updateAsync(int pnID, string pzName, string pzAddress, string pzEmail, string pzPhone, CancellationToken pCt)
    {
        zProceduceName = "dbo.UpdateAuthor @id , @name , @address , @email , @phone";
        await DataProvider.Instance.executeNonQueryAsync(zProceduceName, pCt, new object[] { pnID, pzName, pzAddress, pzEmail, pzPhone });
        await base.updateAsync(pnID, pzName, pzAddress, pzEmail, pzPhone, pCt);
    }

Usually in c# you want to extend upon your base class, and replace only when necessary.通常在 c# 中,您希望扩展您的基类,并且仅在必要时替换。 This is why functions are not virtual by default.这就是为什么函数默认不是虚拟的。 However if the variable values are the only difference you can use a factory to create a specific instance instead.但是,如果变量值是唯一的区别,您可以使用工厂来创建特定实例 However if the "BaseDAL" class should not be used directly you can use the concept of abstract classes.但是,如果不应直接使用“BaseDAL”类,则可以使用抽象类的概念。 You should either:您应该:

  1. Add an abstract function to get the procedures' names添加一个抽象函数来获取过程的名称
  2. Move calls to the DataProvider to protected functions and make all other functions abstract (calling the protected functions in the inheriting classes).将对 DataProvider 的调用移至受保护的函数,并使所有其他函数抽象(在继承类中调用受保护的函数)。

You are needlessly over-relying on virtual inheritance.您不必要地过度依赖虚拟继承。 It seems the only purpose for the zProceduceName is that you need to pass an additional parameter, and you can't change the signature because you are forcing yourself into inheritance. zProceduceName的唯一目的似乎是您需要传递一个额外的参数,并且您不能更改签名,因为您强迫自己进行继承。

public interface IDal
{
     Task<DataTable> loadDataAsync();
     Task insertAsync(string pzName, string pzAddress, 
                   string pzEmail, string pzPhone, CancellationToken pCt);
     Task updateAsync( int pnID ,string pzName, 
                       string pzAddress, string pzEmail, 
                       string pzPhone, CancellationToken pCt);
     Task deleteAsync( int pnID,CancellationToken pCt);
}

 public class AuthorDal : BaseDal, IDal
{
   public async Task<DataTable> loadDataAsync()
   {
    return await base.loadDataAsync("dbo.LoadAuthor");
   }
   // etc.  Methods are not "override" (but might need "new")
}

public class BaseDal
{
    protected async Task<DataTable> loadDataAsync(string proceduceName)
    {
        return await DataProvider.Instance.executeQueryAsync(proceduceName);
    }
    // etc. methods are protected but not virtual with an extra parameter.
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM