StackOverflowException通过动态引用访问嵌套

StackOverflowException通过动态引用访问嵌套

本文介绍了StackOverflowException通过动态引用访问嵌套类的成员时,的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经定义了从的BindingList派生并有一个嵌套的非泛型类泛型类:

 类通用< T> ; :&的BindingList LT;通用< T> .Inner> 
{
公共类内
{
公共对象的Foo {搞定;组; }
}
}



A StackOverflowException

<$ p:code>尝试通过像这样动态引用访问属性时发生的mscorlib $ p> 动态D =新的通用<串GT; .Inner();
VAR值= d.Foo; // StackOverflowException

VAR值= d.Bar // StackOverflowException为好,而不是
//'RuntimeBinderException就像你所期望的,当
//试图访问一个非 - 现有会员

这是最小再现我能够做。



这的BindingList派生是一个重要的细节,如果我将其更改为列表程序正确执行。


$ 2 b $ b

为什么会出现这种情况。



编辑:



这是呼叫顶部堆栈:

  [托管到本机过渡] 
mscorlib.dll中System.RuntimeTypeHandle.Instantiate(System.Type的[! ]研究所)
mscorlib.dll中!System.RuntimeType.MakeGenericType(System.Type的[]实例)
Microsoft.CSharp.dll!Microsoft.CSharp.RuntimeBinder.Semantics.CType.CalculateAssociatedSystemTypeForAggregate(Microsoft.CSharp。 RuntimeBinder.Semantics.AggregateType aggtype)
Microsoft.CSharp.dll!Microsoft.CSharp.RuntimeBinder.Semantics.CType.CalculateAssociatedSystemType(Microsoft.CSharp.RuntimeBinder.Semantics.CType SRC)
Microsoft.CSharp.dll! Microsoft.CSharp.RuntimeBinder.Semantics.CType.AssociatedSystemType.get()
Microsoft.CSharp.dll!Microsoft.CSharp.RuntimeBinder.Semantics.TypeManager.GetAggregate(Microsoft.CSharp.RuntimeBinder.Semantics.AggregateSymbol AGG,微软。 CSharp.RuntimeBinder.Semantics.AggregateType atsOuter,Microsoft.CSharp.RuntimeBinder.Semantics.TypeArray typeArgs)
Microsoft.CSharp.dll!Microsoft.CSharp.RuntimeBinder.Semantics.TypeManager.GetAggregate(Microsoft.CSharp.RuntimeBinder.Semantics。 AggregateSymbol AGG,Microsoft.CSharp.RuntimeBinder.Semantics.TypeArray typeArgsAll)
Microsoft.CSharp.dll!Microsoft.CSharp.RuntimeBinder.Semantics.TypeManager.GetAggregate(Microsoft.CSharp.RuntimeBinder.Semantics.AggregateSymbol AGG,Microsoft.CSharp .RuntimeBinder.Semantics.TypeArray typeArgsAll)
Microsoft.CSharp.dll!Microsoft.CSharp.RuntimeBinder.Semantics.TypeManager.SubstTypeCore(Microsoft.CSharp.RuntimeBinder.Semantics.CType类型,Microsoft.CSharp.RuntimeBinder.Semantics.SubstContext pctx)
Microsoft.CSharp.dll!Microsoft.CSharp.RuntimeBinder.Semantics.TypeManager.SubstTypeArray(Microsoft.CSharp.RuntimeBinder.Semantics.TypeArray taSrc,Microsoft.CSharp.RuntimeBinder.Semantics.SubstContext pctx)


解决方案

非常感谢您的指正!我调查了这一点,我要说非常有趣的时刻,我发现我是对的。



首先,这不是BUG!这是微软团队是如何解决这个问题。同样所有我上面所说的,我相信写的是真的!



因此​​,正如我说你最终与不定式循环,并得到计算器,但在我看来,你得到它非常非常快。因此,没有任何长期当你没有你的机器的任何访问,只是它看起来像它已经死了。我开始挖掘更深的BindingList的结构和这里的结果。



我创建

 类示例< T> :1级<例< T>> 
{
公共字符串名称=111;
}

公共类1级< T>
{

}

和在主

 动态D =新例<串GT;(); 
VAR值= d.Name;

和它的作品!然后,我添加了另一个层次。



 公共类1级< T> :级别< T> 
{

}

公共类级别2< T>
{

}

和我有计算器。我改成

 公共类1级< T> :级别
{

}

公共类级别2
{

}

和它再次工作!



所以我觉得刚才说的,从微软的家伙...所以这是没有办法通过后,最高等级和抛出异常



现在让我们来看看的BindingList< T>

 公共类的BindingList< T> :收集<​​; T> ;, 
IBindingList的,IList的,ICollection的,IEnumerable的,ICancelAddNew,
IRaiseItemChangedEvents

通知收藏< T>



和看列表< T>

 公共类List< T> :IList的< T> ;,的ICollection< T> ;, 
的IList,ICollection的,IReadOnlyList< T> ;, IReadOnlyCollection< T> ;,的IEnumerable< T> ;,
IEnumerable的

刚刚接口....



因此它与列表,但不与的BindingList!我的实例证明!我认为他们这样做是故意停止不定式循环。


I have defined a generic class that derives from BindingList and has a nested non-generic class:

class Generic<T> : BindingList<Generic<T>.Inner>
{
    public class Inner
    {
        public object Foo { get; set; }
    }
}

A StackOverflowException occurs in mscorlib when attempting to access the Value property via a dynamic reference like so:

dynamic d = new Generic<string>.Inner();
var value = d.Foo; // StackOverflowException

var value = d.Bar    // StackOverflowException as well, not a
                     // 'RuntimeBinderException' like you would expect when
                     // trying to access a non-existing member

This is the smallest reproduction i was able to make.

Deriving from BindingList is an important detail, if i change it to a List the program executes correctly.

Why does this happen?

Edit:

This is the top of the call stack:

[Managed to Native Transition]
mscorlib.dll!System.RuntimeTypeHandle.Instantiate(System.Type[] inst)
mscorlib.dll!System.RuntimeType.MakeGenericType(System.Type[] instantiation)
Microsoft.CSharp.dll!Microsoft.CSharp.RuntimeBinder.Semantics.CType.CalculateAssociatedSystemTypeForAggregate(Microsoft.CSharp.RuntimeBinder.Semantics.AggregateType aggtype)
Microsoft.CSharp.dll!Microsoft.CSharp.RuntimeBinder.Semantics.CType.CalculateAssociatedSystemType(Microsoft.CSharp.RuntimeBinder.Semantics.CType src)
Microsoft.CSharp.dll!Microsoft.CSharp.RuntimeBinder.Semantics.CType.AssociatedSystemType.get()
Microsoft.CSharp.dll!Microsoft.CSharp.RuntimeBinder.Semantics.TypeManager.GetAggregate(Microsoft.CSharp.RuntimeBinder.Semantics.AggregateSymbol agg, Microsoft.CSharp.RuntimeBinder.Semantics.AggregateType atsOuter, Microsoft.CSharp.RuntimeBinder.Semantics.TypeArray typeArgs)
Microsoft.CSharp.dll!Microsoft.CSharp.RuntimeBinder.Semantics.TypeManager.GetAggregate(Microsoft.CSharp.RuntimeBinder.Semantics.AggregateSymbol agg, Microsoft.CSharp.RuntimeBinder.Semantics.TypeArray typeArgsAll)
Microsoft.CSharp.dll!Microsoft.CSharp.RuntimeBinder.Semantics.TypeManager.GetAggregate(Microsoft.CSharp.RuntimeBinder.Semantics.AggregateSymbol agg, Microsoft.CSharp.RuntimeBinder.Semantics.TypeArray typeArgsAll)
Microsoft.CSharp.dll!Microsoft.CSharp.RuntimeBinder.Semantics.TypeManager.SubstTypeCore(Microsoft.CSharp.RuntimeBinder.Semantics.CType type, Microsoft.CSharp.RuntimeBinder.Semantics.SubstContext pctx)
Microsoft.CSharp.dll!Microsoft.CSharp.RuntimeBinder.Semantics.TypeManager.SubstTypeArray(Microsoft.CSharp.RuntimeBinder.Semantics.TypeArray taSrc, Microsoft.CSharp.RuntimeBinder.Semantics.SubstContext pctx)
解决方案

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.

这篇关于StackOverflowException通过动态引用访问嵌套类的成员时,的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-21 09:00