c# - "dynamic"构建器模式的关键字隐藏了扩展方法

标签 c# .net dynamic extension-methods

<分区>

我最近在测试某些东西时遇到了 dynamic 关键字的奇怪行为。这不是我迫切需要解决的问题,因为我只是在试验,但我想知道是否有人可以阐明正在发生的事情

我有一个构建器,它返回一个 HttpWebRequest 对象和一个关于 HttpWebRequest 的扩展方法。

我的构建器方法之一采用 string 参数。当我向 builder 方法传递一个字符串时,整个过程都有效,但我向它传递了一个 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 对象的工作方式有些奇怪。但任何解释将不胜感激。

最佳答案

发生这种情况是因为传递 dynamic 参数会使 C# 编译器将表达式的返回类型(即 .SetBody(dynamicString))视为 dynamic(相关 explanation of method return types with dynamic parameters)。

扩展方法仅作为常规方法与 dynamic 对象一起使用,而不是作为扩展方法(请参阅 Eric Lippert's answer 了解对此的解释),因此您会看到编译时错误。

关于c# - "dynamic"构建器模式的关键字隐藏了扩展方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38768492/

相关文章:

c# - 如何在 C# 中列出 .zip 文件夹的内容?

javascript - OData $top 和 PageSize 对 Web API 性能没有影响

c# - 如何在 asp.net mvc 3 中不使用 ajax 的情况下渲染某些特定 div 中的部分 View ?

c# - 更改默认 Windows 键盘快捷键

c# - Windows XP 应用程序 (.NET/C#) 调整大小问题

class - 是否可以在 typescript 中创建动态 getter/setter?

c# - 我可以对事件目录使用基于 token 的身份验证吗?

.net - 在 C# 服务中设置 ASP.Net 缓存 PrivateBytesLimit

.net - 与编码(marshal)结合的反射不起作用

qt - 如何在Qt中正确链接共享的Linux库?