C# 在一个函数中返回一个实际实例,该函数在三种情况下都有一个T?

C# 在一个函数中返回一个实际实例,该函数在三种情况下都有一个T?,c#,.net-core,C#,.net Core,我创建了一个函数,该函数将从url获取数据,然后反序列化Async到T对象 public async Task<T> PostAsync<T>(string url,string param) { var response= await httpClient.GetAsync(url,new HttpContent(param)); if(response is null) { //I want to return T.

我创建了一个函数,该函数将从url获取数据,然后反序列化Async到T对象

public async Task<T> PostAsync<T>(string url,string param)
{
    var response= await httpClient.GetAsync(url,new HttpContent(param));
    
    if(response is null)
    {
      //I want to return T.
    }
    if(!response.Content is null)
    {
        //return new T();
    }
    var str=await response.Content.ReadAsStringAsync();
    return JsonSerializer.DeserializeAsync<T>(str);
}
公共异步任务PostAsync(字符串url,字符串参数)
{
var response=await-httpClient.GetAsync(url,new-HttpContent(param));
if(响应为空)
{
//我想还T。
}
如果(!response.Content为空)
{
//返回新的T();
}
var str=await response.Content.ReadAsStringAsync();
返回JsonSerializer.DeserializeAsync(str);
}
我想做的是:

  • 如果响应为空,则返回
    newt()
  • 如果响应不为空,但r
    response.StatusCode
    NoContent
    ,则返回
    newt()
    ,其中
    T.issucess=true
  • 否则返回反序列化异步()
    但是我不知道T是什么类,并且T可能没有
    issucess

    的属性,在不限制
    T
    选项的情况下,您可以完成的最佳任务是使用包装类。想想这样的事情:

    公共类响应包装器
    {
    公共T数据{get;}
    公共bool IsSuccess{get;}
    public ResponseWrapper():this(false){}
    公共响应包装器(bool isSuccess)
    {
    IsSuccess=IsSuccess;
    }
    公共响应包装器(T数据):此(true)
    {
    数据=数据;
    }
    }
    
    然后您可以这样使用它:

    公共异步任务PostAsync(字符串url,字符串参数)
    {
    var response=await-httpClient.GetAsync(url,new-HttpContent(param));
    if(响应为空)
    {
    返回新的ResponseWrapper();
    }
    如果(!response.Content为空)
    {
    返回新的ResponseWrapper(true);
    }
    var str=await response.Content.ReadAsStringAsync();
    var data=await JsonSerializer.DeserializeAsync(str);
    返回新的ResponseWrapper(数据);
    }
    
    您需要为类型T指定类型约束,以便1)创建清空结果对象,2)将IsSuccess设置为true

    public interface IPostResult {
        bool IsSuccess { get; set; }
    }
    
    // type T has public parameterless constructor, and supports IPostResult interface (has IsSuccess property)
    public async Task<T> PostAsync<T>(string url,string param) where T: IPostResult, new()
    {
        var response= await httpClient.GetAsync(url,new HttpContent(param));
        
        if(response is null)
        {
            return new T();
        }
        if(!response.Content is null)
        {
            var r = new T();
            r.IsSuccess = true;
            return r;
        }
    
        var str=await response.Content.ReadAsStringAsync();
        return JsonSerializer.DeserializeAsync<T>(str);
    }
    
    公共接口IPostResult{
    bool issucess{get;set;}
    }
    //类型T具有公共无参数构造函数,并支持IPostResult接口(具有IsSuccess属性)
    公共异步任务PostAsync(字符串url,字符串参数),其中T:IPostResult,new()
    {
    var response=await-httpClient.GetAsync(url,new-HttpContent(param));
    if(响应为空)
    {
    返回新的T();
    }
    如果(!response.Content为空)
    {
    var r=新的T();
    r、 IsSuccess=true;
    返回r;
    }
    var str=await response.Content.ReadAsStringAsync();
    返回JsonSerializer.DeserializeAsync(str);
    }
    
    能够做
    新T()
    T
    必须是无参数构造函数的约束,因此添加
    其中T:new()
    约束。这需要
    T
    具有公共无参数构造函数,以确保
    new T()是有效的呼叫。谢谢@Camilo Terevinto。你的建议是什么?使用这个包装器还是只返回响应?我想做一个其他人可以使用的帖子功能,而不必写if-else语句。@liang。好吧,那由你决定。我在这里分享的模式非常常见。但是,这是防止限制
    T
    的唯一方法。如果成功将str获取到T,则T具有IsSuccess属性?是的,T声明为支持IPostResult接口,以便您可以在PostAsync内分配其IsSuccess属性。您尝试过吗?它能正常运行吗?我运行它时出错