【问题标题】:When is it best to use static functions in ASP.NET?什么时候最好在 ASP.NET 中使用静态函数?
【发布时间】:2010-12-12 09:56:44
【问题描述】:

我一直在想,在 ASP.NET 中什么时候使用静态函数,什么时候不使用?

使用它们的优点和缺点是什么,在性能、遵循良好实践等各个方面(以及更多,无论你认为什么是相关的)。

【问题讨论】:

  • @cdonner 和@preet .. 感谢您的链接.. 但我正在寻找社区对静态方法的全面输入,因为我对它们不太清楚.. 再次感谢.. :)
  • asp.net 与一般的 C# 或 .NET 相对吗?
  • @Russell Steen .. 请原谅我,但我不知道区别.. 你能详细说明一下吗.. 实际上我在 asp.net 中寻找一般,但想知道C# 和 .net 的区别(如果有的话).. 谢谢 :)

标签: asp.net performance static-methods


【解决方案1】:

缺点:

  • 线程问题(静态函数不需要调用实例,因此很容易从代码的不同部分调用它们,如果它们读/写到共享状态,则该状态可能会在多个-线程环境,例如 ASP.NET)
  • 难以进行单元测试(因为静态函数不需要对象实例,因此不可能注入构造函数,这意味着注入依赖项的唯一方法是将它们作为参数传递给函数本身)

优点:

  • 性能(这是有问题的 - 在大多数情况下,与代码的其他部分相比,性能提升完全可以忽略不计)

【讨论】:

  • 能否请您详细说明一下,或者您能否提供一些指向该方向的指示......谢谢
  • 语义不是另一个好处:某些行为不依赖于封闭的实例来运行,因此将它们标记为这样更“正确”。
  • @ehdv 是性能的扩展 - 只是消除了不必要的实例。
【解决方案2】:

静态方法的唯一主要缺点是它几乎完全不可单元测试。该方法的用户必须绑定到具体方法,而不能绑定到抽象,因此即使不是不可能,也很难伪造或模拟。

但是,这可能是也可能不是问题,具体取决于代码。

您要注意的另一件事是静态数据在对服务器的所有请求中是通用的。

【讨论】:

  • 对于刚开始 ASP.NET 的开发人员来说,这也非常令人困惑。
【解决方案3】:

在某些情况下,静态是合适的解决方案,就像任何应用程序一样。任何时候你有一些对象应该存在于应用程序范围内,而不是在请求范围内,它应该是静态的,你应该使用静态方法来访问和操作它。

例如,这是我最近为 ASP.NET 应用程序编写的一段代码,它本质上是一个序列化程序缓存。序列化器的创建成本很高,只要我们的应用程序存在,我们就可以为每种类型重复使用相同的序列化器,因此无需在每个请求线程中为它们浪费时间:

注意:这已被剥离以展示静态方面)

public class XmlSerializerUtility
{
    private static Dictionary<Type, XmlSerializer> serializers = new Dictionary<Type, XmlSerializer>();
    private static object sync = new object();

    public static T Deserialize<T>(string input)
    {
       XmlSerializer xs = GetSerializer(typeof(T));
        using (StringReader sr = new StringReader(input))
        {
            return (T)xs.Deserialize(sr);
        }
    }

    public static XmlDocument Serialize(object input)
    {
        XmlDocument doc = new XmlDocument();
        XmlSerializer xs = GetSerializer(input.GetType());
        using (MemoryStream stream = new MemoryStream())
        {
            xs.Serialize(stream, input);
            stream.Position = 0;
            doc.Load(stream);
        }
        return doc;
    }

    private static XmlSerializer GetSerializer(Type type)
    {
        lock (sync)
        {
            XmlSerializer xs = null;
            if (!serializers.ContainsKey(type))
            {
                xs = new XmlSerializer(type);
                serializers.Add(type, xs);
            }
            else
            {
                xs = serializers[type];
            }
            return xs;
        }
    }
}

【讨论】:

  • @Rex M,你的Dictionary&lt;Type, XmlSerializer&gt; 毫无意义,XmlSerializer 已经使用了高级缓存技术,它不会为相同类型创建两次相同的临时程序集。一个简单的new XmlSerializer(type) 就可以完成这项工作。我曾经做过同样的事情,只是发现lock 语句和更新序列化程序一样慢:-)
  • @Darin 我想你可能弄错了。 XmlSerializerFactory 确实使用缓存,但不能很好地支持泛型类型。 XmlSerializer(无工厂)不缓存。
  • @Rex M,根据文档 (msdn.microsoft.com/en-us/library/…),如果您使用任何 ctors:XmlSerializer.XmlSerializer(Type)XmlSerializer.XmlSerializer(Type, String):XML 序列化基础结构动态生成程序集以进行序列化和反序列化指定的类型。基础架构会找到并重用这些程序集。
  • 文档确实提供了一个缓存序列化程序的示例,但它使用了一个特殊的构造函数:XmlSerializer(Type, XmlRootAttribute)
  • @Darin 感谢您的链接。我提供的代码示例非常精简 - 真正的代码示例确实具有其他维度并使用其他 XmlSerializer ctor。这个类是在分析应用程序之后构建的,并产生了可衡量的收益——所以它当然不是毫无意义的。这里的唯一目的是演示静态在 ASP.NET 中有用的情况,仅此而已。
猜你喜欢
  • 2010-11-18
  • 2011-08-11
  • 2010-11-29
  • 2011-01-06
  • 2012-05-24
  • 1970-01-01
  • 1970-01-01
  • 2021-11-06
  • 2012-02-06
相关资源
最近更新 更多