如何使用Field <t>和Type?</t>

时间:2011-09-12 16:11:21

标签: c# generics linq-to-dataset

我有一个方法可以确定DataTable

中列的最小值和最大值
public void GetMinMaxRange( DataTable data, string valueColumnName )
{
   var min = data.AsEnumerable().Min(m => m.Field<double>(valueColumnName));
   var max = data.AsEnumerable().Max(m => m.Field<double>(valueColumnName));
}

我想重构这个:

public void GetMinMaxRange( DataTable data, string valueColumnName )
{
   DataColumn column = data.Columns[valueColumnName];
   var min = data.AsEnumerable().Min(m => m.Field<column.DataType>(valueColumnName));
   var max = data.AsEnumerable().Max(m => m.Field<column.DataType>(valueColumnName));
}

我需要确定数据类型并使用它而不是硬编码m.Field<double>。怎么做?

更新 至于为什么我想计算最小和最大

之间的差异
    public static double/decimal/int GetMinMaxRange<T>(DataTable data, 
          string valueColumnName) where T : IComparable<T>
    {
        DataColumn column = data.Columns[valueColumnName];
        var min = data.AsEnumerable().Min(m => m.Field<T>(valueColumnName));
        var max = data.AsEnumerable().Max(m => m.Field<T>(valueColumnName)); ;
        return max - min;
    }

3 个答案:

答案 0 :(得分:6)

简单地将其创建为通用应该有效:

public void GetMinMaxRange<T>( DataTable data, string valueColumnName ) 
                                                             where T : IComparable<T>
{
   DataColumn column = data.Columns[valueColumnName];
   var min = data.AsEnumerable().Min(m => m.Field<T>(valueColumnName));
   var max = data.AsEnumerable().Max(m => m.Field<T>(valueColumnName));
}

然后您将用作:

GetMinMaxRange<MyType>(dataTable, valueColumnName);

答案 1 :(得分:2)

如果您想在运行时使用此功能,则无法使用泛型。您可以像这样重写您的方法:

public void GetMinMaxRangeTest(DataTable data, string valueColumnName)
{
    DataColumn column = data.Columns[valueColumnName];
    var min = data.AsEnumerable().Min(m => Convert.ChangeType(m[valueColumnName], column.DataType));
    var max = data.AsEnumerable().Max(m => Convert.ChangeType(m[valueColumnName], column.DataType));
}

我在列表中对此进行了测试,如下所示:

List<string> num = new List<string>() { 
    "1", "2", "3", "-1", "11", "10", "100"
};
var min = num.AsEnumerable().Min(m => Convert.ChangeType(m, typeof(int)));

并产生正确的结果:-1。

答案 2 :(得分:1)

你不能这么简单。 column.DataType 将是一个SqlDbType,因为只会在运行时知道,所以编译器无法验证它是IComparable