2016-10-05 102 views
2

我在工作中遇到了一个奇怪的错误,它发生在我尝试访问特殊类的特殊方法中的动态属性时。经过研究,我发现了那个问题的代码,但我仍然不知道为什么。尝试从ExpandoObject获取动态提示时出现“System.StackOverflowException”错误

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

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

+0

堆栈溢出异常主要发生因为事情充满了堆得满满的,那溢出堆栈可能会或可能不会与问题相关的实际代码位置。你可以确保在你使用该方法时堆栈还没有满吗? –

+0

看起来像一个微软bug!如果你注释掉'int b = x.AAA'这行''它可以正常工作!我会在Microsoft.Connect上报告这一点。 –

+2

谁投票结束这个不清楚? OP提供了可显示问题的可编译代码! –

回答

3

有一个开放问题#7527CoreFX

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

具有以下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) 
     { 
     } 
    } 
} 
+0

很高兴地说,这现在是一个封闭的问题。期待.NET Core的下一个版本的修复。 –

相关问题