/** * We want to protect against infinite recursion when the schema is recursive. We look into a thread local * to see if we have been into this if so, we execute the bypass function otherwise we execute the main function. * Before executing the main function, we ensure that we create a marker so that if we come back here recursively * we can detect it. * * The infinite loop happens in ToString(), Equals() and GetHashCode() methods. * Though it does not happen for CanRead() because of the current implemenation of UnionSchema's can read, * it could potenitally happen. * We do a linear seach for the marker as we don't expect the list to be very long. */ private T Protect <T>(Func <T> bypass, Func <T> main, RecordSchema that) { if (seen == null) { seen = new List <RecordSchemaPair>(); } else if (seen.FirstOrDefault((rs => rs.first == this && rs.second == that)) != null) { return(bypass()); } var p = new RecordSchemaPair(this, that); seen.Add(p); try { return(main()); } finally { seen.Remove(p); } }
public RecordSchemaPair(RecordSchema first, RecordSchema second) { this.first = first; this.second = second; }