如何在c#中实现接口的同时创建公共静态方法

本文关键字:创建 静态方法 接口 实现 | 更新日期: 2023-09-27 17:57:43

我有以下接口

public interface IQueryBuilder
{
    SqlCommand Build(IReportDataSource dataSource, List<IReportColumn> columns, List<IReportRelationMapping> relationMappings, IReportFilterMapping filters, List<IReportColumn> columsToSortBy, ReportFormat reportFormat);
    string GetSqlClause(List<IReportFilter> reportFilters, ref List<IDataParameter> sqlParams);
}

但是,我希望能够直接访问实现中的方法GetSqlClause

以下是我如何实现上述

public class QueryBuilder : IQueryBuilder
{
    public SqlCommand Build(IReportDataSource dataSource, List<IReportColumn> columns, List<IReportRelationMapping> relationMappings, IReportFilterMapping filters, List<IReportColumn> columsToSortBy, ReportFormat reportType)
    {
        //Do something awsome!!!
        string sqlQuery = "";
        List<IDataParameter> sqlParameters = new List<IDataParameter>();
        return this.GetSqlCommand(sqlQuery, sqlParameters);
    }
    private SqlCommand GetSqlCommand(string sqlQuery, List<IDataParameter> sqlParams)
    {
        var command = new SqlCommand(sqlQuery);
        foreach (IDataParameter dataParameter in sqlParams)
        {
            command.Parameters.Add(dataParameter);
        }
        return command;
    }

    public static string GetSqlClause(List<IReportFilter> reportFilters, ref List<IDataParameter> sqlParams)
    {
        string sqlFilter = "";
        if (reportFilters != null && reportFilters.Any())
        {
            //At this point we know there are some filter to add to the list
            var firstFilter = reportFilters.First();
            foreach (var reportFilter in reportFilters)
            {
                var parameter = GenerateDbParameter("p" + sqlParams.Count, reportFilter.FormattedValue, SqlDbType.NVarChar);
                ....
                ....
            }
        }
        return sqlFilter;
    }
    private static IDataParameter GenerateDbParameter(string parameterName, object parameterValue, SqlDbType parameterType)
    {
        if (string.IsNullOrEmpty(parameterName) || parameterValue == null)
        {
            throw new ArgumentException();
        }
        var parameter = new SqlParameter("@" + parameterName, parameterType)
        {
            Value = parameterValue
        };
        return parameter;
    }

}

因为我在GetSqlClause方法上使用static,所以我得到了一个错误

无法实现接口成员,因为它是静态的。

解决这个问题的好办法是什么?如何直接访问我的GetSqlClause

如何在c#中实现接口的同时创建公共静态方法

如果你想让你的方法是静态的实现一个接口,语言不会允许你这样做,但你可以用几种方法来解决它:

  • 如果从静态上下文访问整个实现是有意义的,那么您可以简单地声明一个singleton对象:

    public static QueryBuilder Instance { get; } = new QueryBuilder();
    

    现在您可以访问QueryBuilder.Instance静态属性,该属性的值实现IQueryBuilder

  • 通过显式方法实现。这是一个实现接口方法的附加实例方法,其签名不会与类中的另一个方法冲突。

    string IQueryBuilder.GetSqlClause(List<IReportFilter> reportFilters, ref List<IDataParameter> sqlParams)
    {
        // Call the static method, this is *not* a recursive call
        return GetSqlClause(reportFilters, ref sqlParams);
    }
    

    显式实现的一般语法是:

    ReturnType InterfaceName.MethodName(ParamType param)
    {
        ...
    }
    
  • 另一个(更简单的)解决方案是使用两个不同的方法名称。

C#不支持实现接口方法的静态成员。