代码之家  ›  专栏  ›  技术社区  ›  Samantha Branham

如何解决C在调用泛型类型上的静态函数时的局限性

  •  1
  • Samantha Branham  · 技术社区  · 16 年前

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

    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;
    }
    

    有没有办法克服这种令人沮丧的限制?

    编辑:下面这段话是胡说八道,但我保留它,所以其中一个答案对未来的读者来说是有意义的:

    用户以及我的其他类实现 IDataModel . IDATAMODEL 只需要1个方法, FromDataRow(DataRow row) . 将where放入函数原型显然没有帮助。

    2 回复  |  直到 16 年前
        1
  •  9
  •   Marc Gravell    16 年前

    当你只需要一种方法的时候,想想功能…也许是 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)

        2
  •  3
  •   Bevan    16 年前

    在示例代码中,使用静态方法从数据行创建用户:

    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 & GT; 要求类型具有无参数构造函数。