在 Console App 和 Excel DNA 中使用 IComparer 时发现相互矛盾的结果

问题描述 投票:0回答:0

需要构建一个在 Excel 中使用的 UDF,使用 Excel DNA,以呈现以锯齿状方式特别排序的结果,使用 C# 的 IComparer 我很惊讶,因为我没有得到预期的结果。

虽然在控制台应用程序中使用相同的代码,但结果运行良好,使用的代码是:

using System;
using System.Linq;
using System.Collections.Generic;

namespace Clxn
{
    public static class fComparer
    {
        static void Main(string[] args)
        {
            object[,] MainRange =
            {
                { "c", "E", "B" },
                { "b", "A", "B" },
                { "A", "D", "D" },
                { "F", "D", "C" }
            };

            int Cntr = 0;
            object[] SortingKey = (from object x in MainRange select x).ToArray();
            object[,] Rxlt = new object[SortingKey.Length, MainRange.GetLength(1) + 1];

            for (int xCol = 0; xCol < Rxlt.GetLength(1); xCol++)
            {
                Cntr = 0;
                for (int xRow = 0; xRow < Rxlt.GetLength(0); xRow++)
                {
                    if (xCol == 0) { Rxlt[xRow, 0] = SortingKey.OrderBy(x => x, new fxl_ComparerObjects()).ToArray()[(Rxlt.GetLength(0) * (xCol)) + xRow]; }
                    else
                    {
                        object[] OrderedSlice = SlicedColumn(MainRange, xCol - 1).ToArray().OrderBy(f => f, new fxl_ComparerObjects()).ToArray();
                        if (Rxlt[xRow, 0] == OrderedSlice[Cntr]) { Rxlt[xRow, xCol] = OrderedSlice[Cntr]; Cntr++; }
                    }
                    if (Cntr >= MainRange.GetLength(0)) Cntr = 0;
                }
            }

            for (int xRow = 0; xRow < Rxlt.GetLength(0); xRow++)
            {
                for (int xCol = 0; xCol < Rxlt.GetLength(1); xCol++) { Console.Write(Rxlt[xRow, xCol] + "\t"); }
                Console.WriteLine("");
            }
        }

        internal static IEnumerable<T> SlicedColumn<T>(this T[,] array, int column)
        {
            for (var i = array.GetLowerBound(0); i <= array.GetUpperBound(0); i++) { yield return array[i, column]; }
        }

        internal class fxl_ComparerObjects : IComparer<object>
        {
            public int SorterIndex { get; set; }
            public int Compare(object x, object y)
            {
                double xVal, yVal;
                var xIsVal = double.TryParse(x.ToString(), out xVal);
                var yIsVal = double.TryParse(y.ToString(), out yVal);
                if (xIsVal && yIsVal) return xVal.CompareTo(yVal);
                if (!xIsVal && !yIsVal) return x.ToString().CompareTo(y.ToString());
                if (xIsVal) return -1;
                return 1;
            }
        }

        internal class fxl_ComparerArrays : IComparer<object[]>
        {
            public int SorterIndex { get; set; }
            public int Compare(object[] x, object[] y)
            {
                double xVal, yVal;
                bool xIsNumber = double.TryParse(x.GetValue(SorterIndex - 1).ToString(), out xVal);
                bool yIsNumber = double.TryParse(y.GetValue(SorterIndex - 1).ToString(), out yVal);
                if (xIsNumber && yIsNumber) return xVal.CompareTo(yVal);
                else if (!xIsNumber && !yIsNumber) return x.GetValue(SorterIndex - 1).ToString().CompareTo(y.GetValue(SorterIndex - 1).ToString());
                else if (xIsNumber) return -1;
                else return 1;
            }
        }
    }
}

,在Console App的情况下,根据需要和预期,导致首先生成一个排序的键列,然后从双维数组中每个相关列的值仅在匹配时放置,在第一次匹配时,即:

然而,令人惊讶的是,用于 Excel 的相同代码导致结果如下:

即尽管使用相同的代码,但值被分散以填充每一列和每一行,但完全相同。

在调试时,我也发现了一些值,虽然相同,但根据剪辑如下,声明不相等,尽管两个数组变量的第一个都是“A”:

将光标悬停在如下语句上,也发现结果不相等,即生成false:

这背后的原因可能是什么?

提前感谢您的所有贡献。

c# excel excel-dna icomparer
© www.soinside.com 2019 - 2024. All rights reserved.