2016-08-04 41 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