参见英文答案 >
Extension method and dynamic object3个
我最近在测试时遇到了动态关键字的奇怪行为.这不是我迫切需要解决的问题,因为我只是在尝试,但我想知道是否有人可以透露正在发生的事情
我最近在测试时遇到了动态关键字的奇怪行为.这不是我迫切需要解决的问题,因为我只是在尝试,但我想知道是否有人可以透露正在发生的事情
我有一个构建器,它在HttpWebRequest上返回一个HttpWebRequest对象和一个扩展方法.
我的一个构建器方法采用字符串参数.当我将构建器方法传递给字符串时,整个过程都有效,但我传递了一个动态变量,它是一个不再有效的字符串.
似乎应该返回类型HttpWebRequestBuilder的构建器方法现在返回动态.
注意
要使其工作,请注释掉.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,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"; } }
我猜这是动态对象工作方式的奇怪之处.但任何解释都将非常感激.
解决方法
发生这种情况是因为传递动态参数使得C#编译器将表达式的返回类型(即.SetBody(dynamicString))视为动态参数(相关的
explanation of method return types with dynamic parameters).
扩展方法仅作为常规方法使用动态对象,而不是扩展方法(有关此内容的解释,请参阅Eric Lippert’s answer),因此会看到编译时错误.