I have defined a generic class that derives from BindingList and has a nested non-generic class:
class Generic : BindingList.Inn
Thank you very much for your correction! I investigated this I would say very interesting moment and found that I was right.
First of all, this is not a BUG! This is just how the Microsoft team solved this issue. Again all what I wrote above I believe is true!
So as I said you end up with an infinitive loop and get StackOverflow, but it seems to me that you get it very very fast. So no any long periods when you have no any access to your machine and just it looks like it's dead. I started digging deeper into the structure of BindingList and here the results.
I created
class Example<T> : Level1<Example<T>>
{
public string Name = "111";
}
public class Level1<T>
{
}
and in the main
dynamic d = new Example<string>();
var value = d.Name;
and it works! Then I added another level
public class Level1<T> : Level2<T>
{
}
public class Level2<T>
{
}
and I got StackOverflow. I changed to
public class Level1<T> : Level2
{
}
public class Level2
{
}
and it works again!
So I think that the guys from Microsoft just said ... so this is the max level after no way through and throw the exception.
Now let's look at BindingList<T>
public class BindingList<T> : Collection<T>,
IBindingList, IList, ICollection, IEnumerable, ICancelAddNew,
IRaiseItemChangedEvents
Notice Collection<T>
And look at List<T>
public class List<T> : IList<T>, ICollection<T>,
IList, ICollection, IReadOnlyList<T>, IReadOnlyCollection<T>, IEnumerable<T>,
IEnumerable
Just interfaces....
Therefore it works with List but not with BindingList!My example proves that!I believe they did it intentionally to stop infinitive looping.
I think the problem is in this place
Generic<T> :BindingList<Generic<T>.Inner>
Notice you use the declared class as a generic parameter in the parent class BindingList. So I believe reflection just ends up with an infinitive loop and you get StackOverflow.
When you use
var d = new Generic<string>.Inner();
compiler just replaces it with Generic.Inner so it is the same like
Generic<string>.Inner d = new Generic<string>.Inner();
But when you use
dynamic d = new Generic<string>.Inner();
You really use reflection. Again reflection starts digging deeper in your class structure and it goes like... your class => BindingList = > generic parameter of BindingList => your class(because it's a generic parameter of BindingList) = > BindingList = > and so on until you get StackOverflow.
You can change to Generic<T> : BindingList<string>
to break this infinitive loop and it works!