2013-05-03 65 views
0

我不明白爲什麼編譯器認爲我的dto在lambda表達式內是動態的。 這是一個錯誤或有一個有效的理由?動態與lambda的奇怪行爲。 c#.net 4

[TestFixture] 
public class DynamicTest 
{ 
    public class Dto 
    { 
     public string Value { get; set; } 
    } 

    public Dto ToDto(dynamic d) 
    { 
     return new Dto(); 
    } 

    [Test] 
    public void dto_is_typed() 
    { 
     // var is Dto 
     var dto = ToDto(new { dummy = true }); 
     dto.Value = "val"; 

     Assert.Inconclusive("yust for intellisense test"); 
    } 

    [Test] 
    public void dto_is_dynamic_inside_an_action_with_dynamic_type() 
    { 
     Action<dynamic> act = o => 
      { 
       // dto is dynamic 
       var dto = ToDto(o); 
       dto.ThisIsNotAProperty = 100; 
      }; 


     var ex = Assert.Throws<Microsoft.CSharp.RuntimeBinder.RuntimeBinderException>(() => 
      { 
       act(new {dummy = true}); 
      }); 

     Assert.IsTrue(ex.Message.EndsWith("does not contain a definition for 'ThisIsNotAProperty'")); 
    } 
} 
+1

你的問題沒有意義。你是否收到錯誤信息?你的測試失敗了嗎?你期望它做什麼?是什麼讓你認爲「編譯器認爲你的動態?」 – 2013-05-03 10:08:13

+0

測試通過。我沒有編譯異常,但運行時異常 – 2013-05-03 10:12:25

+0

什麼是運行時異常?它引發異常的代碼是什麼? – 2013-05-03 10:22:46

回答

4

它在lambda表達式中的事實有點不相關。你已經得到了有效的:

dynamic o = GetValueFromSomewhere(); 
var dto = ToDto(o); 

現在的dto類型是dynamic,因爲表達式ToDto(o)是一個動態表情:您使用的是動態值(o)作爲參數。儘管您知道只有一種方法可以解決,但語言規則強制調用表達式的類型爲dynamic

你可以很容易改變它,只是不使用var

Action<dynamic> act = o => 
{ 
    // dto is dynamic 
    Dto dto = ToDto(o); 
    dto.ThisIsNotAProperty = 100; 
}; 

現在,這將編譯失敗 - 這是我假設你想要的。

+1

「儘管你知道只有一種方法可以解決,但語言規則強制調用表達式的類型是動態的」..這就是答案。謝謝! – 2013-05-03 10:28:40

1

dto是動態的,因爲它是接收動態參數的方法的返回值。
A dynamic參數導致超載結果在運行時發生,從而使編譯器稱爲確切方法未知。

+1

挑剔的是,*參數*是動態的,這使結果變得動態 - 事實上*參數*是'動態的'。如果你有'var dto = ToDto(null);'那麼這不會是一個動態調用。 – 2013-05-03 10:13:51

+0

@JonSkeet:我總是混合那兩個。我的意思是這個說法。修正了,謝謝 – 2013-05-03 10:15:57