1

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

我分别使用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呢?
4

4 回答 4

11

您在这里不一定需要动态,您只需要一个通用接口(在这种情况下它们都有):

private Department ExecuteCommand<T>(T databaseCommand) where T : IDbCommand

但是,在这种情况下,由于您没有对类型做任何特别有趣的事情T(据我所知),因此以下方法签名就足够了:

private Department ExecuteCommand(IDbCommand databaseCommand)

一般来说,如果没有通用接口,我建议使用外观模式,并简单地将方法调用委托给实际实现的等价物。

于 2013-03-14T12:07:03.763 回答
2

它看起来像AseCommandand SqlCommandboth implement 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如果它还没有。

尽管正如rich.okelly 指出的那样,看起来并没有真正的理由首先在这里使用泛型。

于 2013-03-14T12:09:34.083 回答
0

回答#2:

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

用您想要检查的任何类型替换对象。

于 2013-03-14T12:08:55.963 回答
0

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

一般来说,如果你想找出一个对象的类型,你总是可以使用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;
        }

未在 VS 中验证,但它应该可以工作。

于 2013-03-14T12:38:20.477 回答