将数据类作为变量传递给函数

时间:2014-11-04 21:17:37

标签: c#

我正在尝试为C#中的API调用构建一个可重用的模块。我想将它用于几种不同的API。但我无法将我的数据类作为变量动态传递给处理API调用的函数。

所以,让我们说,例如,我称之为两个完全不同的API,我们称之为#34; Api#1"和#34; Api#2"。我有以下课程:

// This is the format of the response from Api #1 GET
public class Api01Get
{
    public int orderId { get; set; }
    public DateTime orderDate { get; set; }
}

// This is the format of the response from Api #2 GET
public class Api02Get
{
    public bool isGreen { get; set; }
    public string name { get; set; }
}

这是对我的功能的调用。如果我直接使用我的一个数据类,它可以正常工作:

var result = CallAPI<Api02Get>(baseAddress, requestUri);

但这并不能让我获得灵活性。

这是我的函数的定义(我在这里省略了其他不影响事情的参数):

private async Task<TResult> CallAPI<TResult>(Uri baseAddress, string requestUri)
{
    using (var client = new HttpClient()) 
    {
        client.BaseAddress = baseAddress;
        client.DefaultRequestHeaders.Accept.Clear();
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

        HttpResponseMessage response = new HttpResponseMessage();
        response = await client.GetAsync(requestUri);
        if (response.IsSuccessStatusCode)   
        {
            TResult result = await response.Content.ReadAsAsync<TResult>();
        }
    }

    // do other stuff...

    return result;
}

现在这就是我被挂断的地方。我必须以不正确的方式思考这个问题,但我想要做的就是这样的事情,例如:

object apiModel;

switch (whichAPI)
{
    case "API_01_GET":
        apiModel = new Api01Get();
        break;

    case "API_02_GET":
        apiModel = new Api02Get();
        break;

    // Other cases...

    default:
        break;
}    

var result = CallAPI<apiModel>(baseAddress, requestUri);

尝试最后一行时出错。 &#34;类型或命名空间名称&#39; apiModel&#39;找不到(你是否错过了使用指令或汇编引用?)&#34;。我尝试了其他的东西,但这个版本似乎让我最接近,所以这就是我发布的内容。

所以我不确定如何实现这一点,或者可能有一个更好的方法。我感谢任何反馈,如果有必要,我很乐意澄清。提前谢谢。

1 个答案:

答案 0 :(得分:0)

不幸的是,如果没有额外的反射来动态调用CallAPI<T>,你就不能在这里使用泛型。

幸运的是,HttpContentExtensions有额外的重载,允许您传入Type。您只需要重载您的方法并对ReadAsAsync稍作调整。

private async Task<object> CallAPI(Uri baseAddress, string requestUri, Type apiType)
{
    using (var client = new HttpClient()) 
    {
        ....

        if (response.IsSuccessStatusCode)   
        {
            object result = await response.Content.ReadAsAsync(apiType);
        }
    }

    ....

    return result;
}

您可能仍需要在此之前更改部分代码,因为您仍然遇到object