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

generic object creation with type as function parameter in c#

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

如果成功或解析有问题,我想 return 任何 T 的空对象(当前列出或只是自定义对象)。

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

不管这是对还是错的做法。问题是 default(T) 将 return 默认值 对于 类型 ,对于 引用类型 null。如果你想要一个"empty object"(新对象)那么你将不得不使用new constraintnew它(实例化它)

例子

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

    ...

    return new T();

}

注意 : 虽然有一些注意事项

new constraint (C# Reference)

The new constraint specifies that any type argument in a generic class declaration must have a public parameterless constructor. To use the new constraint, the type cannot be abstract.


其他资源

default value expressions (C# programming guide)

A default value expression default(T) produces the default value of a type T. The following table shows which values are produced for various types:

  • Any reference type : null
  • Numeric value type : 0
  • bool : false
  • char : [=21=]
  • enum : The value produced by the expression (E)0, where E is the enum identifier.
  • struct : The value produced by setting all value type fields to their default value and all reference type fields to null.
  • Nullable type : An instance for which the HasValue property is false and the Value property is undefined.

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

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

return Activator.CreateInstance(typeof(T));

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

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

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

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