在C#中使用类型作为函数参数的通用对象创建

时间:2019-03-20 08:53:46

标签: c# json generics xamarin default

我正在尝试创建一个通用函数来用Newtonsoft解析我的json结果:

private T ParseResult<T>(string queryResult)
{
    Result res = JsonConvert.DeserializeObject<Result>(queryResult);

    if (res.Success == 1)
    {
        try
        {
            return JsonConvert.DeserializeObject<T>(JsonConvert.SerializeObject(res.data));
        }
        catch (Exception)
        {
            return default(T);
        }
    }
    return default(T);
}

如果成功或解析存在问题,我想返回一个空的对象,无论它是什么T(当前是列表或只是自定义对象)。

我的问题是当前解决方案正在返回null而不是一个空对象。如何实现返回值永远不会为空。

3 个答案:

答案 0 :(得分:5)

不管这是对是错。问题是default(T)将为类型返回默认,对于引用类型null。如果要使用“空对象” (新对象),则必须用完new constraintnew(实例化)

示例

private T ParseResult<T>(string queryResult) where T : new()
{

    ...

    return new T();

}

注意 :尽管有一些警告

new constraint (C# Reference)

  

新约束指定泛型类中的任何类型参数   声明必须具有公共的无参数构造函数。要使用   新约束,类型不能是抽象的。


其他资源

default value expressions (C# programming guide)

  

默认值表达式default(T)产生以下内容的 default 值:   输入T。下表显示了产生的值   各种类型:

     
      
  • 任何引用类型:null
  •   
  • 数值类型:0
  •   
  • boolfalse
  •   
  • char\0
  •   
  • enum:由表达式 (E)0产生的值,其中Eenum标识符。
  •   
  • struct:通过将所有值类型字段设置为其 default 值并将所有引用类型字段设置为null而产生的值。
  • li>   
  • 可空类型:HasValue属性为false且Value属性未定义的实例。
  •   

答案 1 :(得分:0)

T可以是没有默认构造函数的类:在这种情况下,新的T()将是无效的语句。

如果要使用默认对象返回,则可以使用Activator.CreateInstance代替如下所示返回default(T)

return Activator.CreateInstance(typeof(T));

如果要在其中传递参数,请按以下方式使用:

return (T)Activator.CreateInstance(typeof(T), args);

答案 2 :(得分:0)

感谢您的答复。我最终创建了该功能,该功能似乎可以正常工作,我认为这是一种更好的方法:

    private static T ParseResult<T>(string queryResult) where T : new()
    {
        try
        {
            Result<T> res = JsonConvert.DeserializeObject<Result<T>>(queryResult);

            if (res.Success == 1)
            {
                return res.Data;
            }
            return new T();
        }
        catch (Exception) {
            return new T();
        }
    }

internal class Result<T>
{
    [JsonProperty("success")]
    public int Success { get; set; }
    [JsonProperty("data")]
    public T Data { get; set; }
}