【问题标题】:generic object creation with type as function parameter in c#在 C# 中使用类型作为函数参数创建通用对象
【发布时间】:2019-03-20 08:53:45
【问题描述】:

我正在尝试创建一个通用函数来使用 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);
}

如果 Success 或解析有问题,我想返回一个 T 的空对象(当前列出或只是自定义对象)。

我的问题是当前的解决方案返回 null 而不是空对象。我怎样才能实现返回值永远不会为空。

【问题讨论】:

  • 也许你应该在这种情况下接受null。这是区分空数据对象和不存在数据对象的唯一方法,对吧?
  • JsonConvert.DeserializeObject&lt;T&gt;(JsonConvert.SerializeObject(res.data)) 看起来很老套。也许您可以将Result 设为通用(如Result&lt;T&gt;)?

标签: c# json generics xamarin default


【解决方案1】:

不管这是对还是错。问题是default(T) 将返回 typedefaultReference Typesnull。如果你想要一个 "empty object"(新对象),那么你将不得不使用 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) 产生一个默认值 输入T。下表显示了为 各种类型:

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

【讨论】:

    【解决方案2】:

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

    如果您想返回默认对象,您可以使用Activator.CreateInstance 而不是返回default(T),如下所示:

    return Activator.CreateInstance(typeof(T));
    

    如果你想在其中传递参数,那么使用如下:

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

    【讨论】:

      【解决方案3】:

      感谢您的回复。我最终创建了这个似乎有效的功能,我认为这是一种更好的方法:

          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; }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-12-08
        • 1970-01-01
        • 1970-01-01
        • 2012-05-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多