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