【问题标题】:How to convert string value to generic type parameter? [duplicate]如何将字符串值转换为泛型类型参数? [复制]
【发布时间】:2021-09-23 12:13:56
【问题描述】:

如何将泛型方法类型参数作为变量传递给它?下面给出的是我想要实现的粗略示例。这只是为了演示目的,而不是实际代码。我可以使用if...elseswitch 来遍历传递的类别并调用具有相应类型参数的泛型方法。

[HttpGet]
[Route("{category}")]
public IActionResult Get(string category)
{
    object data = new object();
    string json = GetData(category);
    if (category == "User")
    {
        data = JsonConvert.DeserializeObject<User>(json);
    }
    else if (category == "Organization")
    {
        data = JsonConvert.DeserializeObject<Organization>(json);
    }

    return Ok(data);
}

假设 GetData 是一个函数,它根据传递的类别为我提供 JSON 格式的集合。我想调用一个泛型方法DeserializeObject&lt;T&gt;(...),它需要一个类型参数。引用类型参数的类与传递的类别有关。如何实现如下所示?

[HttpGet]
[Route("{category}")]
public IActionResult Get(string category)
{
    string json = GetData(category);
    T categoryType = GetCategoryType(category); // what should be here???
    object data = JsonConvert.DeserializeObject<categoryType>(json);

    return Ok(data);
}

【问题讨论】:

  • "如何将泛型方法类型参数作为变量传递给它?" - 这不是泛型意味着要使用的方式。泛型使 static(即编译时)类型信息能够被具体化 - 对于这种情况,您应该坚持良好的老式 vtable 多态性。
  • 一个很好的反例是Get( category: DeleteEntireFileSystem )。你永远不应该让外部/远程客户端完全控制反序列化:它会导致太多的漏洞。
  • 这能回答你的问题吗? Setting generic type at runtime
  • “它为我提供了一个基于传递类别的 JSON 格式的集合” - 我敢打赌 50 美元 这不是它的作用 - 只是因为如果你打电话给GetData( "nextweekslotterynumbers" )不会得到一个包含 7 个数字 0-49 的 JSON 数组。您需要找出究竟是什么数据GetData 可以返回,然后在您的控制器操作中强制执行该限制。这是纵深防御的一部分。
  • @Dai 请不要关注GetData 函数在做什么。只是作为一个例子。

标签: c# generics


【解决方案1】:

JsonConvert.DeserializeObject 是否需要泛型,它也接受Type 对象。泛型在这里不是正确的解决方案。

改用这个重载

JsonConvert.DeserializeObject(json, Type.GetType(yourNamespace + category))

如果您从用户输入中接收类型名称,我强烈建议您维护可能类型的白名单。

【讨论】:

  • 这里的问题是关于任何不适用于 Json.NET 的 DeserializeObject 函数的通用函数。我只是举个例子。
  • 那么副本就是你想要的。如果它只是一些通用代码的示例,那么您应该清楚地说明这一点。我已经回答了被问到的问题
猜你喜欢
  • 2019-09-10
  • 1970-01-01
  • 2012-12-14
  • 1970-01-01
  • 2021-10-25
  • 2020-06-04
  • 2015-01-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多