简体   繁体   English

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

[英]generic object creation with type as function parameter in c#

I'm trying to create a generic function to parse my json result with Newtonsoft: 我正在尝试创建一个通用函数来用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);
}

If there is a problem with Success or the parsing I want to return an empty object of whatever T is (currently lists or just custom objects). 如果成功或解析存在问题,我想返回一个空对象,无论它是什么T(当前是列表或只是自定义对象)。

My problem is that the current solution is returning null instead of an empty object. 我的问题是当前解决方案正在返回null而不是一个空对象。 How can I achieve that the return value will never be null. 我如何实现返回值永远不会为null。

Irregardless of whether this is the right or wrong approach. 不管这是对是错。 The problem is default(T) will return the default for the type , for Reference Types that is null . 问题是default(T)将为该类型返回默认值 ,对于引用类型null If you want an "empty object" (new object) then you will have to use the new constraint and new it up (instantiate it) 如果你想要一个“空对象”(新目标),那么你就必须使用新的约束new它(初始化它)

Example

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

    ...

    return new T();

}

Note : There are caveats though 注意 :尽管有一些警告

new constraint (C# Reference) 新约束(C#参考)

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. 要使用新的约束,类型不能是抽象的。


Additional Resources 其他资源

default value expressions (C# programming guide) 默认值表达式(C#编程指南)

A default value expression default(T) produces the default value of a type T . 默认值表达式default(T)产生类型T默认值。 The following table shows which values are produced for various types: 下表显示了为各种类型生成的值:

  • Any reference type : null 任何引用类型: null
  • Numeric value type : 0 数值类型: 0
  • bool : false boolfalse
  • char : \\0 char\\0
  • enum : The value produced by the expression (E)0 , where E is the enum identifier. enum :由表达式 (E)0产生的值,其中Eenum标识符。
  • struct : The value produced by setting all value type fields to their default value and all reference type fields to null . struct :通过将所有值类型字段设置为其默认值并将所有引用类型字段设置为null
  • Nullable type : An instance for which the HasValue property is false and the Value property is undefined. 可空类型: HasValue属性为false且Value属性未定义的实例。

T could be a class that does not have a default constructor: in this case new T() would be an invalid statement. T可以是没有默认构造函数的类:在这种情况下,新的T()将是无效的语句。

If you want to return with the default object you can use Activator.CreateInstance instead of returning default(T) as below: 如果要使用默认对象返回,则可以使用Activator.CreateInstance而不是如下返回default(T)

return Activator.CreateInstance(typeof(T));

if you want to pass parameters in it, then use as below: 如果要在其中传递参数,请按以下方式使用:

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

Thanks for the responses. 感谢您的答复。 I ended up creating this function which seems to work and I think is a better approach: 我最终创建了该功能,该功能似乎可以正常工作,我认为这是一种更好的方法:

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

and

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM