【问题标题】:"System.StackOverflowException" error when try to get a dynamic proppery from an ExpandoObject [duplicate]尝试从 ExpandoObject 获取动态属性时出现“System.StackOverflowException”错误 [重复]
【发布时间】:2016-10-05 19:50:58
【问题描述】:

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

这是我的代码(我使用 .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()
    {
    }
}

你能告诉我为什么会发生这个错误吗?

【问题讨论】:

  • 堆栈溢出异常的发生主要是因为某些东西已经把堆栈填满了,堆栈溢出的实际代码位置可能与问题有关,也可能无关。当您使用该方法时,您能否确保堆栈尚未满?
  • 看起来像微软的错误!如果您注释掉 int b = x.AAA; 行,它可以正常工作!我会在 Microsoft.Connect 上报告此问题。
  • 谁投票决定关闭这个不清楚? OP提供了演示问题的可编译代码!
  • 看起来类似于这个one 和这个other 一个......我会说不需要ExpandoObject,只需动态x = 0就足够了......
  • @MachineLearning 你是对的:我刚刚用dynamic x = 0; int y = x; 尝试过,但它失败了(但是请注意,你需要y = x;)。看起来这就是答案。这是微软的错误。

标签: c# .net dynamic stack-overflow


【解决方案1】:

CoreFX 存储库中有一个open 问题#7527

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

使用以下repro.txt 解决此错误。

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)
        {
        }
    }
}

【讨论】:

  • 很高兴地说,这是一个已解决的问题。期待下一个 .NET Core 版本的修复。
猜你喜欢
  • 2021-07-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-11
  • 2013-10-08
  • 2013-04-13
  • 1970-01-01
  • 2020-04-02
相关资源
最近更新 更多