这是了解c#中传递给泛型方法的参数类型的正确方法



从我的C# 4.0代码,我想对SybaseMSSQL执行一些查询。正在使用(或将要使用)的数据库将只在运行时决定/知道

我使用AseCommandSqlCommand分别为Sybase和SQL。

我决定创建这样的通用方法:

private Department ExecuteCommand<T>(T databaseCommand) where T : class
{
            Department department = new Department ();
            dynamic command = databaseCommand;
            using (dynamic databaseReader = command.ExecuteReader())
            {
                if (databaseReader.HasRows)
                {
                    while (databaseReader.Read())
                    {
                         department.Employees.Add(this.CreateDepartmentInstance(databaseReader));
                    }
                }
            }
            command.Connection.Dispose();
            return department;
        }

问题:

  1. 有比dynamic更好的选择吗?
  2. 通常知道传递给泛型方法的参数类型的正确方法是什么?
  3. 当然,我可以为Sybase和SQL编写两个单独的方法。但是,当dynamic这样的东西可供使用时,为什么要这样做呢?

您在这里不一定需要动态,您所需要的只是一个公共接口(在这个实例中它们都有):

private Department ExecuteCommand<T>(T databaseCommand) where T : IDbCommand
然而,在这个实例中,由于您没有对类型T做任何特别有趣的事情(据我所知),因此以下方法签名就足够了:
private Department ExecuteCommand(IDbCommand databaseCommand)

一般来说,如果没有公共接口,我建议使用facade模式,并简单地将方法调用委托给实际实现上的等价对象。

看起来AseCommandSqlCommand都实现了IDbCommand,所以你只需要改变类型约束:

private Department ExecuteCommand<T>(T databaseCommand) where T : IDbCommand
{
    Department department = new Department();
    using (IDataReader databaseReader = databaseCommand.ExecuteReader())
    {
        if (databaseReader.HasRows)
        {
            while (databaseReader.Read())
            {
                department.Employees.Add(
                                 this.CreateDepartmentInstance(databaseReader));
            }
        }
    }
    command.Connection.Dispose();
    return department;
}

我想象你还需要改变CreateDepartmentInstance来接受IDataReader,如果它还没有。

虽然有钱。Okelly指出,看起来并没有真正的理由在这里使用泛型。

对#2的回答:

if (typeof(T) == typeof(object) ) {
    // Check for IEnumerable
}

将对象替换为您想要检查的任何类型

在您的情况下,使用公共接口就可以了。

一般来说,如果你想知道一个对象的类型,你总是可以使用isas -操作符。

private Department ExecuteCommand<T>(T databaseCommand) where T : class
{
            Department department = new Department ();
            var command = databaseCommand;
            using (var databaseReader = command.ExecuteReader())
            {
                if ((databaseReader as IDataReader).HasRows)
                {
                    while ((databaseReader as IDataReader).Read())
                    {
                          department.Employees.Add(this.CreateDepartmentInstance(databaseReader));
                    }
                }
            }
            command.Connection.Dispose();
            return department;
        }

相关内容

最新更新