具有HttpMethod参数的通用方法

14
我正在尝试创建一个方法,根据HttpMethod调用其他方法。我的方法看起来像这样:

public async Task<string> CreateAsync<T>(HttpClient client, string url, HttpMethod method, T data, Dictionary<string, string> parameters = null)
{
    switch(method)
    {
        case HttpMethod.Post:
            return await PostAsync(client, url, data);
        case HttpMethod.Put:
            return await PutAsync(client, url, data);
        case HttpMethod.Delete:
            return await DeleteAsync(client, url, parameters);
        default:
            return await GetAsync(client, url, parameters);
    }
}

问题是,开关正在抱怨:

需要一个常量值

而且每个情况都被用红色下划线标出。 有人知道我做错了什么吗?


1
HttpMethod.Post和其他所有的都不是常量,这也是switch语句所期望的。如果你查看源代码,你就会明白为什么了。你可以使用策略模式来解决这个问题。 - Nkosi
3个回答

18

正如已经指出的问题是HttpMethodDeletePost等属性是实例而不是常量或枚举。它们也是可比较的。

我想要补充的是,如果你使用的是C# 7,你可以使用模式匹配来代替if..else if....else if...链:

public async Task<string> CreateAsync<T>(HttpClient client, string url, HttpMethod method, T data, Dictionary<string, string> parameters = null)
{
    switch (method)
    {
        case HttpMethod m when m == HttpMethod.Post:
            return await PostAsync(client, url, data);
        case HttpMethod m when m == HttpMethod.Put:
            return await PutAsync(client, url, data);
        case HttpMethod m when m == HttpMethod.Delete:
            return await DeleteAsync(client, url, parameters);
        default:
            return await GetAsync(client, url, parameters);
    }
}

R#说:https://i.imgur.com/Hn3uUFQ.jpg.. 并建议:https://i.imgur.com/1lD91Xo.jpg - Royi Namir

4
你不能像dasblinkenlight和Nkosi所说的那样做。最简单的解决方法是使用HttpMethod.Method并将硬编码字符串用于case语句。
public async Task<string> CreateAsync<T>(HttpClient client, string url, HttpMethod method, T data, Dictionary<string, string> parameters = null)
{
    switch (method.Method)
    {
        case "POST":
            return await PostAsync(client, url, data);
        case "PUT":
            return await PutAsync(client, url, data);
        case "DELETE":
            return await DeleteAsync(client, url, parameters);
        default:
            return await GetAsync(client, url, parameters);
    }
}

2
由于 HttpMethod 的静态属性,例如 HttpMethod.PutHttpMethod.PostHttpMethod 类的实例,你不能像枚举成员一样在 switch 语句中使用它们作为 case 表达式。
但是这些对象是可比较的,因此您可以在 if-then-else 链中使用它们,或者在 Dictionary<HttpMethod,SomeDelegate> 中使用它们,其中 SomeDelegate 是表示要运行的任务的操作类型。
if (method == HttpMethod.Post) {
    return await PostAsync(client, url, data);
} else if (method == HttpMethod.Put) {
    return await PutAsync(client, url, data);
} else if (method == HttpMethod.Delete) {
    return await DeleteAsync(client, url, parameters);
} else {
    return await GetAsync(client, url, parameters);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接