使用lambda的多态类

Rob*_*der 3 c# lambda

我不确定这是否可行.我正在尝试学习一些关于lambda表达式的知识,因为我和我的好友一起写了一个程序.所以他有一个与MS SQL服务器对话的Database类.我想对类进行一些测试,因此制作了一个简单的压缩数据库,在我的TextFixtureSetup中填充表(现在有2个表),然后在拆解时删除所有数据.他的数据库类使用类似这样的东西进行SQL连接

    protected void WithConnection(Action<SqlConnection> sqlBlock)
    {
        try
        {
            using (SqlConnection connection = new SqlConnection(this.ConnectionString))
            {
                connection.Open();
                sqlBlock(connection);
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine(@"Exception during database connection: {0}", ex);
        }
    }
Run Code Online (Sandbox Code Playgroud)

我想我找到了Jon Skeet用几乎相同的代码回答的帖子./sf/answers/74417871/

我认为这很酷,但我的模拟数据库使用SQLCEReader.我做了一些研究,发现他们共享一个共同的类System.Data.Common.DbDataReader,它只有一个级别.我没有检查过多少,但我在考虑是否有可能使用多态风格的方式来使用WithConnection编程风格,这将允许我使用我的SQLCeDataReader和他的SQLDataReader.有没有办法做到这一点

Dax*_*ohl 5

使用工厂功能.如果你可以只使用一个你的DbConnection所有你Actions不需要泛型:

protected void WithConnection(Action<DbConnection> sqlBlock, Func<DbConnection> dbCxnFactory)
{
    try
    {
        using (DbConnection connection = dbCxnFactory())
        {
            connection.ConnectionString = this.ConnectionString;
            connection.Open();
            sqlBlock(connection);
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine(@"Exception during database connection: {0}", ex);
    }
}
Run Code Online (Sandbox Code Playgroud)

如果你想专门化,SqlConnection只有一些动作,只有一些动作SqlCeConnection,那么你可以使它成为通用的:

protected void WithConnection<T>(Action<T> sqlBlock, Func<T> dbCxnFactory) where T : DbConnection
{
    try
    {
        using (T connection = dbCxnFactory())
        {
            connection.ConnectionString = this.ConnectionString;
            connection.Open();
            sqlBlock(connection);
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine(@"Exception during database connection: {0}", ex);
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您不想将工厂作为参数传入,则可以使用泛型 new()

protected void WithConnection<TCxn>(Action<TCxn> sqlBlock) where TCxn : DbConnection, new()
{
    try
    {
        using (var cxn = new TCxn())
        {
            cxn.ConnectionString = this.ConnectionString;
            cxn.Open();
            sqlBlock(cxn);
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine(@"Exception during database connection: {0}", ex);
    }
}
Run Code Online (Sandbox Code Playgroud)