2016-08-04 69 views
6

我最近碰到一個奇怪的行爲與dynamic關鍵字,而我正在測試的東西。這不是我急需解決的問題,因爲我只是在試驗,但我想知道是否有人可以解釋發生了什麼「動態」關鍵字與生成器模式隱藏擴展方法

我有一個構建器,它返回HttpWebRequest對象和HttpWebRequest上的擴展方法。

我的一個構建器方法需要參數string。整個事情的作品,當我通過建設者的方法一個字符串,但我通過它一個dynamic變量這是一個字符串,它不再工作。

看起來應該返回類型HttpWebRequestBuilder的構建方法現在返回dynamic

下面的代碼是一個簡單的被複制它,也可here

注意

要使其工作,註釋掉線.SetBody(dynamicString)並取消行.SetBody(json)

public class Program 
{ 
    public static void Main() 
    { 
     dynamic dynamicString = "{ \"test\" : \"value\" }"; 
     string json = "{ \"test\" : \"value\" }"; 

     string test = new HttpWebRequestBuilder() 
      .SetRequestType() 
      //.SetBody(json) //uncomment this and it works 
      .SetBody(dynamicString) //uncomment this and it breaks 
      .Build() 
      .ExtensionMethod(); 

     Console.WriteLine(test); 
    } 

} 

public class HttpWebRequestBuilder 
{ 
    private readonly HttpWebRequest _request; 

    public HttpWebRequestBuilder() 
    { 
     Uri uri = new Uri("http://www.google.com"); 
     _request = WebRequest.CreateHttp(uri); 
    } 

    public HttpWebRequestBuilder SetRequestType() 
    { 
     _request.Method = "POST"; 
     _request.ContentType = "application/json"; 

     return this; 
    } 

    public HttpWebRequestBuilder SetBody(string json) 
    { 
     byte[] bytes = Encoding.UTF8.GetBytes(json); 
     _request.ContentLength = bytes.Length; 

     using (Stream writer = _request.GetRequestStream()) 
     { 
      writer.Write(bytes, 0, bytes.Length); 
      writer.Flush(); 
     } 

     return this; 
    } 

    public HttpWebRequest Build() 
    { 
     return _request; 
    } 
} 

public static class WebRequestExtensions 
{ 
    public static string ExtensionMethod(this HttpWebRequest webRequest) 
    { 
     return "extension method worked"; 
    } 
} 

我猜這是奇怪的方式dynamic對象的工作方式。但任何解釋將不勝感激。

回答

7

這是因爲傳遞dynamic參數使得C#編譯器處理該表達式的返回類型,即.SetBody(dynamicString),如dynamic(相關explanation of method return types with dynamic parameters)。

擴展方法僅與dynamic對象一起作爲常規方法使用,而不是作爲擴展方法(請參閱Eric Lippert's answer對此進行解釋),因此會出現編譯時錯誤。

+0

我讀埃裏克在過去的這個問題的答案,但我完全忘了關於它:/ –

1

雖然dasblinkenlight的答案似乎是正確的,請記住,你總是可以通過這種方式重新制定你的代碼避免此問題:

public class Program 
{  public static void Main() 
    { 
     dynamic dynamicString = "{ \"test\" : \"value\" }"; 
     string json = "{ \"test\" : \"value\" }"; 

     var test = new HttpWebRequestBuilder(); 
      test.SetRequestType(); 
      //test.SetBody(json); //still works 
      test.SetBody(dynamicString); // works also now 
      var b = test.Build(); 
      var s = b.ExtensionMethod(); 

     Console.WriteLine(s); 
    } 
} 
+0

感謝你們,當我測試時,我實際上做了類似的事情。問題更多的是讓我明白爲什麼會發生。這可能對別人有幫助,所以我會放棄+1 – Dreagen