“System.StackOverflowException"尝试从ExpandoObject获取动态属性时出

本文关键字:获取 ExpandoObject 动态 属性 StackOverflowException System quot | 更新日期: 2023-09-27 18:11:48

我在工作中遇到了一个奇怪的错误,它发生在我试图访问一个特殊类的特殊方法中的动态属性时。经过研究,我找到了导致这个问题的代码,但我仍然不知道为什么。

下面是我的代码(我使用。net 4.5)
public class MyCommand<TResult>
    : Command<MyCommand<TResult>>
   where TResult : class
{
}
public class MyDacAction : DacActionBase<MyDacAction, MyCommand<string>>
{
    public override void Execute()
    {
        dynamic x = new System.Dynamic.ExpandoObject();
        x.AAA = 100;
        int b = x.AAA;
    }
}
public abstract class DacActionBase<TCommand, TDacCommand>
    where TCommand : class
    where TDacCommand : class, new()
{
    public virtual void Execute()
    {
    }
}
public abstract class Command<TCommand>
   : CommandBase<TCommand>
    where TCommand : class
{
    public virtual void Execute()
    {
    }
}
public abstract class CommandBase<TCommand> where TCommand : class
{
}
class Program
{
    static void Main(string[] args)
    {
        var test = new MyDacAction();
        test.Execute();
    }
}

如果你创建一个控制台应用程序并运行这段代码,你会在这一行看到StackOverflowException

int b = x.AAA;

在测试时,我发现了两个更改,错误将不会被抛出

1。

public class MyCommand
    : Command<MyCommand>
{
}
public class MyDacAction : DacActionBase<MyDacAction, MyCommand>
{
    public override void Execute()
    {
        dynamic x = new System.Dynamic.ExpandoObject();
        x.AAA = 100;
        int b = x.AAA;
    }
}

2。

public abstract class Command<TCommand>
    where TCommand : class
{
    public virtual void Execute()
    {
    }
}

“System.StackOverflowException"尝试从ExpandoObject获取动态属性时出

CoreFX存储库中存在open问题#7527

动态类型解析进入无限递归

和下面的repr .txt来修复这个bug。

namespace SOE2
{
    class Program
    {
        static void Main(string[] args)
        {
            // vvv--- changing "dynamic" to "var" or "string" here fixes the issue
            dynamic parsedDocument = "";
            var mystery = new FailingClass<string>();
            Console.WriteLine("Entering...");
            mystery.FailingMethod(parsedDocument);
            Console.WriteLine("... and we are back!");
            Console.ReadLine();
        }
    }
    public abstract class CommonBase<T>
    {
    }
    // Technically, this class does nothing and deriving from it should be identical to deriving from CommonBase
    public abstract class FailingClassBase<T> : CommonBase<T>
    {
    }
    // However, deriving from CommonBase instead of FailingClassBase here also fixes the issue
    // ----------------------------vvvvvvvvvvvvvvvv
    public class FailingClass<T> : FailingClassBase<FailingClass<T>>
    {
        public void FailingMethod(T src)
        {
        }
    }
}