在什么情况下,此代码会因System.StackOverflowException而出错?
Accounts.Sort((x, y) => string.Compare(x.AccountId, y.AccountId));
更新:
该财产写为:
public string AccountId
{
get { return _accountId; }
set { _accountId = value; }
}
根本没什么特别的。排序也不会被覆盖。
答案 0 :(得分:5)
查看callstack,您将看到一遍又一遍地执行哪个函数。如果这不可能(因为它在生产环境中运行),请提供更多信息。
关于被调用属性调用的内容,调用此函数的位置等
答案 1 :(得分:5)
如果AccountId
做了一件非常重要的事情(任何除了访问本地字段外),那么这是最有可能的赌注。
一个有趣的事实是技术上 Sort
要求排序是可传递的,字符串比较是not always transitive!但这很少会导致堆栈溢出(除非Sort
方法使用某种FP方法); 可能导致它永远运行,但我相信内置类型甚至覆盖了它们(它们检查理论上的最大游程长度和中止,IIRC)。
我会看AccountId
;如果它做了“聪明”的事情(比如从父集合中加载一些值),那么错误就是“聪明”。
答案 2 :(得分:5)
所以我遇到了一个棘手的情况,我在比较方法中得到了StackOverflow异常。
我的比较方法:
public bool Equals(Type rhs)
{
if (rhs == null) return false;
if (this == rhs) return true;
return this.randomField.Equals(rhs.randomField);
}
我的接线员:
public static bool operator ==(Type lhs, Type rhs)
{
if (lhs == null)
return (rhs == null);
else
return lhs.Equals(rhs);
}
所以,发生的是==运算符调用Equals方法,然后在运行行this == rhs
时调用==运算符。解决方案是将行转换为Object.ReferenceEquals(this, rhs)
。
答案 3 :(得分:4)
帐户是否已宣布为List<Account>
?
我想知道Accounts
是否是一个声明为List<Account>
之外的属性 - 例如,IList<Account>
- 并且你有一个带有{的某个静态助手类{1}}未正确实施的扩展方法。当传入的参数为Sort
时,这可能会尝试利用List<T>.Sort
方法,但不会对List<T>
执行必要的转换,从而产生保证List<T>
。
我的意思是这个。假设StackOverflowException
是某个类的属性,看起来像这样:
Account
然后假设其他地方你有这个带有public class AccountManager
{
public IList<Account> Accounts { get; private set; }
public AccountManager()
{
// here in the constructor, Accounts is SET to a List<Account>;
// however, code that interacts with the Accounts property will
// only know that it's interacting with something that implements
// IList<Account>
Accounts = new List<Account>();
}
}
扩展方法的静态类:
Sort
在这种情况下,您发布的代码会抛出public static class ListHelper
{
public static void Sort<T>(this IList<T> list, Comparison<T> comparison)
{
// programmer tries to use the built-in sort, if possible
if (list is List<T>)
{
// only problem is, list is here still typed as IList<T>,
// so this line will result in infinite recursion
list.Sort(comparison);
// the CORRECT way to have done this would've been:
// ((List<T>)list).Sort(comparison);
return;
}
else
{
list.CustomSort(comparison);
return;
}
}
private static void CustomSort<T>(this IList<T> list, Comparison<T> comparison)
{
// some custom implementation
}
}
。
也许StackOverflowException
是自定义集合类的对象,其Accounts
方法调用自身?
Sort
也许public class AccountCollection : IEnumerable<Account> {
// ...
public void Sort(Comparison<Account> comparison) {
Sort(comparison); // infinite recursion
}
// ...
}
属性会自行调用?
AccountId
答案 4 :(得分:2)
StackOverflowException
通常发生在你有一个疯狂的递归调用时。检查Sort
或AccountId
是否在调用自己。如果是这样,请检查这些递归函数的基本情况,并确保它们在它们应该停止时停止。
答案 5 :(得分:2)
仅仅因为此行抛出StackOverflow并不意味着它是导致问题的原因,例如。
void methodA()
{
b();
methodA();
}
这很可能在b()上获得堆栈溢出,因为它是对methodA()的递归调用;
我怀疑递归是围绕这行代码的方法。