使用IComparer <t>类型类

时间:2015-07-15 15:01:01

标签: c# sorting datatable datarow icomparer

我有一个扩展方法,尝试使用IComparer类型的类对多个列对数据表的行进行排序,以进行至少一个排序。

使用仅在运行时知道其名称和数据类型的列创建数据表。排序字符串(“Title ASC,PostedDate DESC”)也在运行时创建。

所以说我的表有列:ID,Name,PostedDate,Num1。我的排序字符串是“PostedDate DESC,Name ASC”,在字符串列“Name”的排序过程中,我想使用自定义类

NaturalSortComparer : IComparer<string>

如果列的dataType等于TComparerType,我试图在OrderBy调用中使用指定的IComparer对象,但我想“不能从我的用法中推断出类型参数”。

有没有人知道我可以解决这个问题的方法?提前谢谢。

public static EnumerableRowCollection<DataRow> OrderBy<TComparerType>(
    this EnumerableRowCollection<DataRow> rows, DataTable table, string orderBy, IComparer<TComparerType> comparer)
{
    if (table == null || string.IsNullOrWhiteSpace(orderBy))
    {
        return rows;
    }

    OrderedEnumerableRowCollection<DataRow> orderedRows = null;
    foreach (string sortString in orderBy.Split(new[] { "," }, StringSplitOptions.None))
    {
        var trimmedSortString = sortString.Trim();

        int directionIndex = trimmedSortString.IndexOf(" DESC", StringComparison.OrdinalIgnoreCase);
        bool isDescending = directionIndex != -1;

        string columnName = isDescending ? trimmedSortString.Substring(0, directionIndex) : trimmedSortString;
        Type columnType = table.Columns[columnName].DataType;

        Func<DataRow,dynamic> selectorFunc = (row => RowSelectors[columnType](row, columnName));

        Type comparerTypeParameter = comparer == null ? null : typeof(TComparerType);
        if (orderedRows == null)
        {
            if (columnType == comparerTypeParameter)
            {
                orderedRows = isDescending 
                    ? rows.OrderByDescending(selectorFunc, comparer) 
                    : rows.OrderBy(selectorFunc, comparer);
            }
            else
            {
                orderedRows = isDescending 
                    ? rows.OrderByDescending(selectorFunc) 
                    : rows.OrderBy(selectorFunc);
            }
        }
        else
        {
            if (columnType == comparerTypeParameter)
            {
                orderedRows = isDescending 
                    ? orderedRows.ThenByDescending(selectorFunc, comparer) 
                    : orderedRows.ThenBy(selectorFunc, comparer);
            }
            else
            {
                orderedRows = isDescending 
                    ? rows.OrderByDescending(selectorFunc) 
                    : rows.OrderBy(selectorFunc);
            }
        }
    }
    return orderedRows ?? rows;
}


private static readonly Dictionary<Type, Func<DataRow, string, dynamic>> RowSelectors =
    new Dictionary<Type, Func<DataRow, string, dynamic>>
{
    {typeof(string),   (row,colName)=>row.Field<string>(colName)},
    {typeof(decimal),  (row,colName)=>row.Field<decimal>(colName)},
    {typeof(int),      (row,colName)=>row.Field<int>(colName)},
    {typeof(short),    (row,colName)=>row.Field<short>(colName)},
    {typeof(float),    (row,colName)=>row.Field<float>(colName)},
    {typeof(double),   (row,colName)=>row.Field<double>(colName)},
    {typeof(bool),     (row,colName)=>row.Field<bool>(colName)},
    {typeof(DateTime), (row,colName)=>row.Field<DateTime>(colName)},
    {typeof(TimeSpan), (row,colName)=>row.Field<TimeSpan>(colName)}
};

1 个答案:

答案 0 :(得分:0)

当你改变

Func<DataRow, dynamic> selectorFunc = (row => RowSelectors[columnType](row, columnName));

Func<DataRow, TComparerType> selectorFunc = (row => RowSelectors[columnType](row, columnName));

你的代码将编译。