当我在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
属性。
它给我的比较一个空值。为什么呢?
如代码所示,在调用Sort()
之前,childNodes
中没有空值,
但在Sort()
之后,有一个空值。为什么呢?
Debug构建和Release构建之间有什么区别?
4.这是一个C#错误吗?我之前遇到过一个C#bug。
答案 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");
}