C # - System.StackOverflowException with Lambda

In what situations is this code error with a System.StackOverflowException?

Accounts.Sort((x, y) => string.Compare(x.AccountId, y.AccountId)); 

Update :
a property is written as:

  public string AccountId { get { return _accountId; } set { _accountId = value; } } 

Nothing special happens at all. Sorting is also not canceled.

+7
sorting c # lambda stack-overflow
source share
6 answers

Look at the column and you will see which function is executed again and again. If this is not possible (because it works inside the production environment, for example), give more information.

about calling invoked properties, where this function is invoked, etc.

+5
source share

If AccountId does something non-trivial (nothing but access to the local field), then this is the most likely bet.

An interesting fact is that Sort technically requires ordering to be transitive, and string comparison is not always transitive ! But this rarely leads to a stackoverflow transition (unless the Sort method uses any FP approach); this may cause it to work forever, but I believe the built-in types even covered it (they check the theoretical maximum length and interrupt, IIRC).

I would look at AccountId ; if he does something “smart” (for example, lazy-load some value from the parent collection), the likelihood that the error is in “smart”.

+5
source share

So, I had a difficult situation when I received StackOverflow exceptions in the comparison method.

My comparison method:

 public bool Equals(Type rhs) { if (rhs == null) return false; if (this == rhs) return true; return this.randomField.Equals(rhs.randomField); } 

My statement:

 public static bool operator ==(Type lhs, Type rhs) { if (lhs == null) return (rhs == null); else return lhs.Equals(rhs); } 

So what happened, the == operator called the Equals method, which then called the == operator when it ran the this == rhs . The solution was to convert the string to Object.ReferenceEquals(this, rhs) .

+5
source share

Here's a non-standard idea:

Are accounts declared as List<Account> ?

I am wondering if Accounts property declared as something other than List<Account> - for example, as IList<Account> - and you have a static helper class somewhere with a Sort extension method that is not Correct. This may try to use the List<T>.Sort when the parameter passed is List<T> , but do this without performing the necessary cast to List<T> , resulting in a guaranteed StackOverflowException .

I mean it. Suppose Account is a property of some class that looks something like this:

 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 interacting with something that implements // IList<Account> Accounts = new List<Account>(); } } 

And then suppose you have this static class elsewhere using the Sort extension method:

 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 } } 

In this case, you sent a StackOverflowException code.


Original answer:

Perhaps Accounts is an object of a custom collection class whose Sort method calls itself?

 public class AccountCollection : IEnumerable<Account> { // ... public void Sort(Comparison<Account> comparison) { Sort(comparison); // infinite recursion } // ... } 

Perhaps the AccountId property calls itself?

 public class Account { // ... public string AccountId { get { return AccountId; } // infinite recursion } // ... } 
+4
source share

StackOverflowException usually occurs when you have a recursive call that is wild. Check if Sort or AccountId calls itself. If so, check the base registers for these recursive functions and make sure they stop when they should stop.

+2
source share

Just because this line throws StackOverflow doesn’t mean that this is the cause of the problem, for example

 void methodA() { b(); methodA(); } 

This will most likely lead to a stack overflow on b (), since it is on a recursive call to method A ();

I suspect that recursion is in the method around this line of code.

+2
source share

All Articles