且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

当访问***Exception通过动态泛型类型的成员:.NET / C#框架的错误?

更新时间:2023-01-17 18:02:24

我创建了一个更短,更给了点 SSCCE 这说明了这个问题:

I created a shorter, more to-the-point SSCCE that illustrates the problem:

class Program
{
    static void Main()
    {
        dynamic obj = new Third<int>();
        Print(obj); // causes stack overflow
    }

    static void Print(object obj) { }
}

class First<T> where T : First<T> { }

class Second<T> : First<T> where T : First<T> { }

class Third<T> : Second<Third<T>> { }

综观调用栈,它似乎是对反弹在C#运行时绑定两个符号之间:

Looking at the call stack, it seems to be bouncing between two pairs of symbols in the C# runtime binder:

Microsoft.CSharp.RuntimeBinder.SymbolTable.LoadSymbolsFromType(
    System.Type originalType
)

Microsoft.CSharp.RuntimeBinder.SymbolTable.GetConstructedType(
    System.Type type,
    Microsoft.CSharp.RuntimeBinder.Semantics.AggregateSymbol agg
)

Microsoft.CSharp.RuntimeBinder.Semantics.TypeManager.SubstTypeCore(
    Microsoft.CSharp.RuntimeBinder.Semantics.CType type, 
    Microsoft.CSharp.RuntimeBinder.Semantics.SubstContext pctx
)

Microsoft.CSharp.RuntimeBinder.Semantics.TypeManager.SubstTypeArray(
    Microsoft.CSharp.RuntimeBinder.Semantics.TypeArray taSrc,
    Microsoft.CSharp.RuntimeBinder.Semantics.SubstContext pctx
)

如果我不得不大胆的猜测,一些泛型类型的限制嵌套你有事情已经成功地粘合剂混淆成递归遍历参与约束与约束自己的类型。

If I had to hazard a guess, some of the generic type constraint nesting you've got going on has managed to confuse the binder into recursively walking the types involved in the constraints along with the constraints themselves.

继续前进,文件在连接错误;如果编译器不能抓到它,运行时粘合剂***也不要用。

Go ahead and file a bug on Connect; if the compiler doesn't get caught by this, the runtime binder probably shouldn't either.

这code例如正常运行:

This code example runs correctly:

class Program
{
    static void Main()
    {
        dynamic obj = new Second<int>();
        Print(obj);
    }

    static void Print(object obj) { }
}

internal class First<T>
    where T : First<T> { }

internal class Second<T> : First<Second<T>> { }

这使我相信(不运行时绑定的内部的很多知识),它的主动检查递归的约束,但只有一层。随着中介类之间,粘结剂最终没有检测到递归并试图走它,而不是。 (不过,这一切都只是猜测。我想将它添加到您的连接错误作为附加信息,并看看是否有帮助。)

This leads me to believe (without much knowledge of the internals of the runtime binder) that it's proactively checking for recursive constraints, but only one level deep. With an intermediary class in between, the binder ends up not detecting the recursion and tries to walk it instead. (But that's all just an educated guess. I'd add it to your Connect bug as additional information and see if it helps.)