为什么此代码仅在从Visual Studio内部运行时才起作用?

时间:2014-08-29 05:16:48

标签: c#

当我在Visual Studio中使用F5(包括Debug或Release版本)时,我的下面的代码工作正常,但是当我直接运行EXE文件时,我得到一个例外:

    System.InvalidOperationException: 未能比较数组中的两个元素。 ---> System.ArgumentException: Hey,C#,you give me a null?
   在 GeometricComposition.GCForm.DataForm.<>c__DisplayClass3.<GenerateTreeNodes>b__1(TreeNode a, TreeNode b) 位置 h:\Projects\C#\GeometricComposition\GeometricComposition\GCForm\DataFormGenerateDistance.cs:行号 124
   在 System.Array.FunctorComparer`1.Compare(T x, T y)
   在 System.Collections.Generic.ArraySortHelper`1.PickPivotAndPartition(T[] keys, Int32 lo, Int32 hi, IComparer`1 comparer)
   在 System.Collections.Generic.ArraySortHelper`1.IntroSort(T[] keys, Int32 lo, Int32 hi, Int32 depthLimit, IComparer`1 comparer)
   在 System.Collections.Generic.ArraySortHelper`1.IntroSort(T[] keys, Int32 lo, Int32 hi, Int32 depthLimit, IComparer`1 comparer)
   在 System.Collections.Generic.ArraySortHelper`1.IntroSort(T[] keys, Int32 lo, Int32 hi, Int32 depthLimit, IComparer`1 comparer)
   在 System.Collections.Generic.ArraySortHelper`1.IntrospectiveSort(T[] keys, Int32 left, Int32 length, IComparer`1 comparer)
   在 System.Collections.Generic.ArraySortHelper`1.Sort(T[] keys, Int32 index, Int32 length, IComparer`1 comparer)
   --- 内部异常堆栈跟踪的结尾 ---
   在 System.Collections.Generic.ArraySortHelper`1.Sort(T[] keys, Int32 index, Int32 length, IComparer`1 comparer)
   在 System.Array.Sort[T](T[] array, Int32 index, Int32 length, IComparer`1 comparer)
   在 System.Collections.Generic.List`1.Sort(Comparison`1 comparison)
   在 GeometricComposition.GCForm.DataForm.GenerateTreeNodes(String rootFormat, String childFormat, FuncRef`3 getChildNodes, Func`3 comparePairs) 位置 h:\Projects\C#\GeometricComposition\GeometricComposition\GCForm\DataFormGenerateDistance.cs:行号 121
   在 GeometricComposition.GCForm.DataForm.DisplayPairsTreeInvoke() 位置 h:\Projects\C#\GeometricComposition\GeometricComposition\GCForm\DataFormGenerateDistance.cs:行号 100
   在 GeometricComposition.GCForm.DataForm.GenerateData(GCFile file) 位置 h:\Projects\C#\GeometricComposition\GeometricComposition\GCForm\DataForm.cs:行号 44
   在 GeometricComposition.GCForm.DataForm.HandleSelectedFileChanged(Object sender, SelectedFileChangedEventArg e) 位置 h:\Projects\C#\GeometricComposition\GeometricComposition\GCForm\DataForm.cs:行号 73
   在 GeometricComposition.SelectedFileChangedEventHandler.Invoke(Object sender, SelectedFileChangedEventArg e)
   在 GeometricComposition.MainForm.OnSelectedFileChanged() 位置 h:\Projects\C#\GeometricComposition\GeometricComposition\MainForm.cs:行号 68
   在 GeometricComposition.MainForm.WorkDockPanel_ActiveContentChanged(Object sender, EventArgs e) 位置 h:\Projects\C#\GeometricComposition\GeometricComposition\MainForm.cs:行号 59
   在 WeifenLuo.WinFormsUI.Docking.DockPanel.OnActiveContentChanged(EventArgs e) 位置 h:\Projects\C#\GeometricComposition\WinFormsUI\Docking\DockPanel.FocusManager.cs:行号 577
   在 WeifenLuo.WinFormsUI.Docking.DockPanel.FocusManagerImpl.RefreshActiveWindow() 位置 h:\Projects\C#\GeometricComposition\WinFormsUI\Docking\DockPanel.FocusManager.cs:行号 402
   在 WeifenLuo.WinFormsUI.Docking.DockPanel.FocusManagerImpl.HookEventHandler(Object sender, HookEventArgs e) 位置 h:\Projects\C#\GeometricComposition\WinFormsUI\Docking\DockPanel.FocusManager.cs:行号 354
   在 WeifenLuo.WinFormsUI.Docking.DockPanel.FocusManagerImpl.LocalWindowsHook.OnHookInvoked(HookEventArgs e) 位置 h:\Projects\C#\GeometricComposition\WinFormsUI\Docking\DockPanel.FocusManager.cs:行号 58
   在 WeifenLuo.WinFormsUI.Docking.DockPanel.FocusManagerImpl.LocalWindowsHook.CoreHookProc(Int32 code, IntPtr wParam, IntPtr lParam) 位置 h:\Projects\C#\GeometricComposition\WinFormsUI\Docking\DockPanel.FocusManager.cs:行号 78
   在 System.Windows.Forms.UnsafeNativeMethods.SetFocus(HandleRef hWnd)
   在 System.Windows.Forms.ContainerControl.FocusActiveControlInternal()
   在 System.Windows.Forms.Form.set_Active(Boolean value)
   在 System.Windows.Forms.Form.WmActivate(Message& m)
   在 System.Windows.Forms.Form.WndProc(Message& m)
   在 System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
   在 System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   在 System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

这不是我第一次遇到这个问题的时间或项目,但这次我决定找出原因。

完整的原始代码是:

...
...
GenerateTreeNodes("P", "FD", GetChildNodesByPitch, ComparePairsDistance);
...
...
private void GenerateTreeNodes(string rootFormat, string childFormat,
        FuncRef<int, string, List<TreeNode>> getChildNodes,
        Func<GCFacePointPair, GCFacePointPair, int> comparePairs)
    {
        int i = 0;
        while (i < fpps.Count)
        {
            TreeNode rootNode = new TreeNode(fpps[i].ToString(rootFormat));
            List<TreeNode> childNodes = getChildNodes(ref i, childFormat);
            childNodes.Sort((TreeNode a, TreeNode b) =>
            {
                if (a == null || b == null)
                    throw new ArgumentNullException("Hey,C#,you give me a null?");
                return comparePairs((GCFacePointPair)a.Tag, (GCFacePointPair)b.Tag);
            });
            rootNode.Nodes.AddRange(childNodes.ToArray());
            FacePointTreeView.Invoke((Func<TreeNode, int>)(FacePointTreeView.Nodes.Add), rootNode);
        }
    }

    private List<TreeNode> GetChildNodesByPitch(ref int index, string format)
    {
        List<TreeNode> childNodes = new List<TreeNode>();
        GCPitch curr = fpps[index].Point.ID;
        while (index < fpps.Count && fpps[index].Point.ID == curr)
        {
            TreeNode node = new TreeNode(fpps[index].ToString(format));
            node.Tag = fpps[index];
            childNodes.Add(node);
            index++;
        }
        return childNodes;
    }

    private int ComparePairsDistance(GCFacePointPair a, GCFacePointPair b)
    { return Math.Sign(a.Distance - b.Distance); }

问题是Sort()之前childNodes中没有空 但是Sort()之后我得到了一个空


显然,必须设置Tag属性。


  1. 它给我的比较一个空值。为什么呢?

  2. 如代码所示,在调用Sort()之前,childNodes中没有空值, 但在Sort()之后,有一个空值。为什么呢?

  3. Debug构建和Release构建之间有什么区别?

  4. 4.这是一个C#错误吗?我之前遇到过一个C#bug。

3 个答案:

答案 0 :(得分:2)

您的代码检查是否存在任何空TreeNode。但是,它也将TreeNode.Tag转换为GCFacePointPair:

return comparePairs((GCFacePointPair)a.Tag, (GCFacePointPair)b.Tag);

我怀疑可能存在尚未设置Tag的TreeNodes。也许您应该添加到测试中,以帮助您调试:

        if (childNodes.FindIndex((TreeNode n) => 
            { return n == null; }) != -1)
            throw new Exception("null 0");
        if (childNodes.FindIndex((TreeNode n) => { 
            return !(n.Tag is GCFacePointPair); }) != -1)
            throw new Exception("Tag not set");

答案 1 :(得分:1)

好吧,我已经解决了这个问题......虽然我还是不知道为什么...... 我保证我的代码中没有错误...... 怎么解决? 这是代码:

...
...
GenerateTreeNodes("P", "FD", GetChildNodesByPitch, ComparePairsDistance);
...
...
private void GenerateTreeNodes(string rootFormat, string childFormat,
            ActionRef2<SortedSet<TreeNode>,int, string> getChildNodes,
            Func<GCFacePointPair, GCFacePointPair, int> comparePairs)
        {
            int index = 0;
            while (index < fpps.Count)
            {
                TreeNode rootNode = new TreeNode(fpps[index].ToString(rootFormat));
                SortedSet<TreeNode> childNodes =
                    new SortedSet<TreeNode>(
                        Comparer<TreeNode>.Create((TreeNode a, TreeNode b) =>
                        {
                            return comparePairs((GCFacePointPair)a.Tag, (GCFacePointPair)b.Tag);
                        }));

                getChildNodes(ref childNodes, ref index, childFormat);

                /*childNodes.Sort((TreeNode a, TreeNode b) =>
                {
                    return comparePairs((GCFacePointPair)a.Tag, (GCFacePointPair)b.Tag);
                });*/

                TreeNode[] nodes = new TreeNode[childNodes.Count];
                childNodes.CopyTo(nodes);
                rootNode.Nodes.AddRange(nodes);
                //rootNode.Nodes.AddRange(childNodes.ToArray());

                FacePointTreeView.Invoke((Func<TreeNode, int>)(FacePointTreeView.Nodes.Add), rootNode);
            }
        }

        private void GetChildNodesByPitch(ref SortedSet<TreeNode> childNodes, ref int index, string format)
        {
            GCPitch curr = fpps[index].Point.ID;
            while (index < fpps.Count && fpps[index].Point.ID == curr)
            {
                TreeNode node = new TreeNode(fpps[index].ToString(format));
                node.Tag = fpps[index];
                childNodes.Add(node);
                index++;
            }
        }

        private int ComparePairsDistance(GCFacePointPair a, GCFacePointPair b)
        { return Math.Sign(a.Distance - b.Distance); }

注意到我只是将List<T>替换为SortedSet<T>并进行一些调整 所以在Add所有节点之后,它就会被排序。

我仍然想知道发布版本会发生什么...... 谁可以帮助我?

答案 2 :(得分:0)

找出错误的地方,检查可能错误的节点的值

var nullIdx = childNodes.FindIndex((TreeNode n) => { return n == null; });
if (nullIdx >= 0)
{
    var nullChild = childNodes[nullIdx];
    // todo nullIdx-1 and nullIdx+1 to maybe check what went wrong
    throw new Exception("null 1");
}