本地新对象或全局静态对象

时间:2015-05-19 14:23:35

标签: c# .net oop

假设我有一个wcf服务

public class DataService : IDataService

假设 我需要在我的服务中的每个方法中使用一个JavaScriptSerializer对象来将我的对象序列化为json字符串并将其发送回调用者 (通过另一个类包装)

我应该

JavaScriptSerializer serializer = new JavaScriptSerializer();

在课堂上的每个方法中,或者我可以只有

private static JavaScriptSerializer serializer = newJavaScriptSerializer();`

在我班上的顶端?

4 个答案:

答案 0 :(得分:2)

在Web服务中使用static变量会产生一些您需要注意的副作用。

考虑到creating a new serializer与实际使用一次相比可忽略不计的开销,我会说你应该有一个局部变量。成本很低,您可以获得很多安全性来抵御奇怪的多线程错误。

答案 1 :(得分:1)

如果您打算经常使用该变量,可以选择将其变为static。该单个变量的内存压力可忽略不计,但可能会对性能产生积极影响。但也需要考虑一些警告。

如果您打算在多线程环境中使用它,一个问题可能是线程安全。文档没有声明它是线程安全的,所以我们必须假设它不是线程安全的。

使用WCF(或任何ASP.NET托管服务)时的另一个考虑因素是static在所有实例之间共享。虽然在这种情况下不太可能,但您的static可能会将信息公开给其他会话,而不是您想要的。

不要在WCF中使用static,除非您非常非常确定这样做是安全的。

答案 2 :(得分:1)

我个人从不会像这样使用静态 - 创建一个新的序列化程序是可以忽略不计的,所以看起来你正在尝试进行微优化,这是你应该避免的。

相反,您可以使用像StructureMap或Unity这样的IoC容器来“构造函数注入”JavaScriptSerializer实例(最好使用接口),但可能(但不是绝对必需)。

像这样,您可以轻松地模拟和替换序列化程序,并创建模块化和可测试的代码,并且可以轻松确定实例的生命周期。

 public class DataService : IDataService
 {
      private readonly IJavaScriptSerializer  _serializer;

      public DataService(IJavaScriptSerializer serializer)
      {
          _serializer = serializer;
      }
 }

在这种情况下,这意味着您编写了一个接口IJavaScriptSerializer,以及一个内部使用JavaScriptSerializer的自定义实现。

答案 3 :(得分:1)

新的总是更好。

总是,特别是当有疑问时,最好只为您的特定操作创建一个辅助类的新实例。它的成本几乎为零,而且是最安全的最简单方法。

只有当您确定帮助者/服务/任何类别是不可变的或您完全理解其行为时,您才真正需要共享它,只有这样您才能在操作之间共享它。

另外,你应该在构造函数中接收所需的所有helper / service / etc对象,最好使用DI来处理所有这些。