2016-10-05 119 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的下一個版本的修復。 –

相關問題