我定义了一个从BindingList派生的通用类,并具有嵌套的非通用类:

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

尝试通过动态引用访问StackOverflowException属性时,mscorlib中会出现Value,如下所示:
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

这是我能做的最小的复制品。

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

为什么会这样?

编辑:

这是调用堆栈的顶部:
[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)

最佳答案

非常感谢您的纠正!我调查了一下,我会说非常有趣的时刻,发现我是对的。

首先,这不是一个BUG!这就是Microsoft团队解决此问题的方法。我上面写的所有内容再次都是真实的!

因此,正如我说的那样,您最终遇到一个不定式循环并获得StackOverflow,但在我看来,您获得它的速度非常快。因此,当您无权访问您的计算机并且看上去已经死了时,再也没有任何长时间。我开始更深入地研究BindingList的结构和结果。

我建立

class Example<T> : Level1<Example<T>>
{
    public string Name = "111";
}

public class Level1<T>
{

}

并在主要
dynamic d = new Example<string>();
var value = d.Name;

而且有效!然后我添加了另一个级别
public class Level1<T> : Level2<T>
{

}

public class Level2<T>
{

}

我得到了StackOverflow。我改为
public class Level1<T> : Level2
{

}

public class Level2
{

}

它再次起作用!

因此,我认为来自Microsoft的人员只是说过...因此,这是无法通过并引发异常的最高级别。

现在让我们看看BindingList<T>
public class BindingList<T> : Collection<T>,
    IBindingList, IList, ICollection, IEnumerable, ICancelAddNew,
    IRaiseItemChangedEvents

通知Collection<T>
看看List<T>
public class List<T> : IList<T>, ICollection<T>,
    IList, ICollection, IReadOnlyList<T>, IReadOnlyCollection<T>, IEnumerable<T>,
    IEnumerable

只是接口(interface)...。

因此,它适用于List而不适用于BindingList!我的示例证明了!我相信他们有意这样做是为了停止不定式循环。

关于c# - 通过动态引用访问嵌套类的成员时出现StackOverflowException,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/19612325/

10-11 00:26