我如何解决C#在Generic类型上调用静态函数的限制

时间:2009-04-09 20:49:33

标签: c# generics extension-methods

我有以下扩展方法,并希望使其更通用,因此我不必为我们域中的每个类实现它。

public static IList<User> ToList(this DataTable table)
{
    IList<User> users = new List<User>();

    foreach (DataRow row in table.Rows)
        users.Add(User.FromDataRow(row));

    return users;
}

有没有办法解决这个令人沮丧的限制?

编辑:以下段落是bollocks,但我保留了它,所以其中一个答案对未来的读者有意义:

用户以及我的其他类实现了IDataModelIDataModel只需要1种方法FromDataRow(DataRow row)。将功能原型放在哪里显然无济于事。

2 个答案:

答案 0 :(得分:9)

当您只需要一种方法时,请考虑Func ...也许是Func<DataRow, T>

public static IList<T> ToList<T>(this DataTable table,
      Func<DataRow,T> converter)
{
    IList<T> list = new List<T>();

    foreach (DataRow row in table.Rows)
        list.Add(converter(row));

    return list;
}

然后拨打table.ToList<User>(User.FromDataRow)

答案 1 :(得分:3)

在您的示例代码中,您使用静态方法从DataRow创建用户:

foreach (DataRow row in table.Rows)
    users.Add(User.FromDataRow(row));

但是,您不能使用static方法来实现接口。

假设您的界面如下所示:

public interface IDataModel {
    void FromDataRow(DataRow row);
}

那么你的User类将有一个实例方法FromDataRow(),而不是静态方法。

如果您的类具有无参数构造函数,那么您可以这样写:

public static IList<T> ToList<T>(this DataTable table)
    where T : IDataModel, new()
{
    IList<T> results = new List<T>();

    foreach (DataRow row in table.Rows)
    {
        T item = new T();
        item.FromDataRow(row);
        results.Add(item);
    }

    return users;
}

IDataModel上的<T>约束要求该类型实现IDataModel new()上的<T>约束要求类型具有无参数构造函数。