【问题标题】:Why were generics used in this context?为什么在这种情况下使用泛型?
【发布时间】:2013-07-22 21:01:00
【问题描述】:
public static string JsonSerializer<T>(T t)
{
    DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T));
    MemoryStream ms = new MemoryStream();
    ser.WriteObject(ms, t);
    string jsonString = Encoding.UTF8.GetString(ms.ToArray());
    ms.Close();
    return json;
}

以上是您典型的 json 辅助方法。 &lt;T&gt;的相关性和将参数作为类型T传递的相关性是什么?

鉴于所有对象都继承自object,我希望这个方法签名是这样的:

public static string JsonSerializer(object t)...

我很欣赏向 SO 社区询问为什么其他人的代码以某种方式读取可能是一种不好的提问方式,但这是在许多文章和教程中都可以找到的一种非常标准的帮助方法,所以我希望这种方法是一个被接受的。

【问题讨论】:

  • 可能是typeof(T)?这是获取变量声明类型的一种方式。
  • 但是我的印象是object.GetType()可以代替这个吗?感谢您的回复。
  • 是的,但是typeof(T) 在编译时解析,而GetType() 在运行时解析。
  • @CédricBignon 那又怎样?
  • @delnan 所以,它稍微快一点。没有其他的。我认为在这种情况下不会有任何区别。

标签: c# generics object serialization methods


【解决方案1】:

这只是为了让您不必使用GetType() 来获取DataContractJsonSerializerT 类型。它还停止值类型的装箱。

【讨论】:

  • 但是我的印象是object.GetType()可以代替这个吗?谢谢你的回答。
  • 确保你也理解了答案的第二部分。您可以将泛型方法与 int 之类的值类型一起使用,而无需将其装箱到对象中。
  • @Alden - 这是我现在难以理解的答案的第二部分。我是否正确地说,如果您在这种情况下将 int 作为 t 传递并且它期望一个对象,它会将 int(值类型)装箱为对象(引用),然后将此“装箱”对象传递给 WriteObject 方法可以直接作为 int 传递吗?再次感谢所有回复。到目前为止真的很有帮助。
  • 在这种情况下,无论如何它最终都会被装箱,因为 WriteObject 将对象作为第二个参数。所以我猜唯一的优化是编译时typeof()。不过一般来说,您可以将值类型作为泛型参数传递,而无需将其装箱。
【解决方案2】:

原因是优化。当某些函数是通用的时,编译器将生成与调用中使用的不同类型一样多的该函数的实例。这意味着每个特定的实例都将知道其确切类型并启用特定于参数类型的优化,例如:32 位算术而不是 64 位、避免不必要的装箱、调用非虚拟方法等。

JsonSerializer&lt;T&gt;(T t) 这种特殊情况下,收益可能不会那么大。一般来说,特别是当函数被调用数百万次时,签名中这种复杂性的增益可能非常值得。

【讨论】:

  • 在这种特殊情况下?我没有看到从t 调用的任何虚拟方法,并且由于ser.WriteObject(Stream, object),在所有情况下都会出现装箱。
  • 非常感谢朋友,感谢您的回答。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-25
  • 1970-01-01
  • 2019-01-02
  • 2017-01-07
  • 2015-05-20
  • 2012-07-10
相关资源
最近更新 更多