什么时候使用静态类在C# [英] When to use static classes in C#

查看:131
本文介绍了什么时候使用静态类在C#的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下是 MSDN必须说的内容何时使用静态类


  CompanyInfo 
{
public static string GetCompanyName(){returnCompanyName; }
public static string GetCompanyAddress(){returnCompanyAddress; }
// ...
}

使用静态类作为
组织的单位,而不是与特定对象相关联的

另外,一个静态类可以使你的
实现更简单和更快
,因为你不必创建一个
对象来调用它的方法。
以有意义的方式在类中组织方法
是有用的,
例如系统命名空间中的Math类
的方法。


对我来说,这个例子似乎没有涵盖静态类的很多可能的使用场景。在过去,我使用静态类的无状态套件的相关函数,但这是关于它。那么,在什么情况下应该(而不应该)一个类被声明为静态的?

解决方案

我在早期的Stack Overflow回答中写了我的静态类的想法:
单一方法类 - 最佳方法?



我曾经喜欢用静态方法填充的实用程序类。他们大大地巩固了助手方法,否则会导致冗余和维护地狱。他们很容易使用,没有实例化,没有处置,只是fire'n'forget。我想这是我第一次不知不觉的尝试创建一个面向服务的架构 - 大量的无状态服务,只是做了他们的工作,没有别的。


$ b

有方法UtilityClass.SomeMethod快乐地buzzes沿。突然,我们需要稍微改变功能。大多数功能是相同的,但我们必须改变几个部分。如果它不是一个静态方法,我们可以做一个派生类,并根据需要更改方法内容。因为它是一个静态方法,我们不能。当然,如果我们只需要在旧方法之前或之后添加功能,我们可以创建一个新类并调用其中的旧类 - 但这只是粗糙的。​​



接口问题



由于逻辑原因,静态方法不能通过接口定义。由于我们不能覆盖静态方法,当我们需要通过它们的接口传递它们时,静态类是无用的。这使得我们无法使用静态类作为策略模式的一部分。我们可能会通过传递代理而不是接口



测试



基本上与上面提到的接口困难一起。由于我们交换实现的能力非常有限,我们也会遇到用测试代码替换生产代码的麻烦。再次,我们可以将它们包装起来,但是它需要我们改变我们的代码的大部分,只是为了能够接受包装器而不是实际的对象。



Fosters blob



由于静态方法通常用作实用程序方法,实用方法通常具有不同的用途,类填充了非相干功能 - 理想情况下,每个类在系统中应该有单一的目的。



参数蠕变



首先,这个可爱的和无害的静态方法可能需要一个参数。随着功能的增长,添加了几个新参数。不久,添加了可选的更多参数,因此我们创建方法的重载(或者只是添加默认值,在支持它们的语言中)。很久以前,我们有一个方法需要10个参数。只有前三个是真正需要的,参数4-7是可选的。但是如果指定了参数6,则需要填充7-9。如果我们创建了一个类,其目的是做这个静态方法所做的,我们可以通过获取所需的参数来解决这个问题。构造函数,并允许用户通过属性设置可选值,或者同时设置多个相互依赖的值的方法。此外,如果一个方法已经发展到这种复杂性,它很可能需要在自己的类中。



要求消费者创建一个实例没有原因的类



最常见的参数之一是:为什么要求我们类的消费者创建一个实例来调用这个方法,使用后的实例?在大多数语言中创建类的实例是非常便宜的操作,因此速度不是问题。向消费者添加额外的代码行是为将来构建更可维护的解决方案的基础的低成本。最后,如果你想避免创建实例,只需创建一个单例包装器的类,允许轻松重用 - 虽然这确实要求你的类是无状态的。如果它不是无状态的,你仍然可以创建处理一切的静态包装器方法,同时仍然给你长远的所有好处。最后,你还可以创建一个隐藏实例化的类,就像它是一个单例:MyWrapper.Instance是一个属性,只返回 new MyClass();



只有一个Sith交易在绝对



当然,有一些例外,我不喜欢静态方法。真正的实用程序类,不会带来任何膨胀的风险是静态方法的优秀案例 - System.Convert作为示例。如果你的项目是一次性的,没有对未来维护的要求,整体架构真的不是很重要 - 静态或非静态,并不重要 - 开发速度,但是。



标准,标准,标准!

使用实例方法并不会阻碍你使用静态方法,反之亦然。只要有分化背后的推理,它是标准化的。没有什么比查看使用不同实现方法扩展的业务层更糟的了。


Here's what MSDN has to say under When to Use Static Classes:

static class CompanyInfo
{
    public static string GetCompanyName() { return "CompanyName"; }
    public static string GetCompanyAddress() { return "CompanyAddress"; }
    //...
}

Use a static class as a unit of organization for methods not associated with particular objects. Also, a static class can make your implementation simpler and faster because you do not have to create an object in order to call its methods. It is useful to organize the methods inside the class in a meaningful way, such as the methods of the Math class in the System namespace.

To me, that example doesn't seem to cover very many possible usage scenarios for static classes. In the past I've used static classes for stateless suites of related functions, but that's about it. So, under what circumstances should (and shouldn't) a class be declared static?

解决方案

I wrote my thoughts of static classes in an earlier Stack Overflow answer: Class with single method -- best approach?

I used to love utility classes filled up with static methods. They made a great consolidation of helper methods that would otherwise lie around causing redundancy and maintenance hell. They're very easy to use, no instantiation, no disposal, just fire'n'forget. I guess this was my first unwitting attempt at creating a service-oriented architecture - lots of stateless services that just did their job and nothing else. As a system grows however, dragons be coming.

Polymorphism

Say we have the method UtilityClass.SomeMethod that happily buzzes along. Suddenly we need to change the functionality slightly. Most of the functionality is the same, but we have to change a couple of parts nonetheless. Had it not been a static method, we could make a derivate class and change the method contents as needed. As it's a static method, we can't. Sure, if we just need to add functionality either before or after the old method, we can create a new class and call the old one inside of it - but that's just gross.

Interface woes

Static methods cannot be defined through interfaces for logic reasons. And since we can't override static methods, static classes are useless when we need to pass them around by their interface. This renders us unable to use static classes as part of a strategy pattern. We might patch some issues up by passing delegates instead of interfaces.

Testing

This basically goes hand in hand with the interface woes mentioned above. As our ability of interchanging implementations is very limited, we'll also have trouble replacing production code with test code. Again, we can wrap them up, but it'll require us to change large parts of our code just to be able to accept wrappers instead of the actual objects.

Fosters blobs

As static methods are usually used as utility methods and utility methods usually will have different purposes, we'll quickly end up with a large class filled up with non-coherent functionality - ideally, each class should have a single purpose within the system. I'd much rather have a five times the classes as long as their purposes are well defined.

Parameter creep

To begin with, that little cute and innocent static method might take a single parameter. As functionality grows, a couple of new parameters are added. Soon further parameters are added that are optional, so we create overloads of the method (or just add default values, in languages that support them). Before long, we have a method that takes 10 parameters. Only the first three are really required, parameters 4-7 are optional. But if parameter 6 is specified, 7-9 are required to be filled in as well... Had we created a class with the single purpose of doing what this static method did, we could solve this by taking in the required parameters in the constructor, and allowing the user to set optional values through properties, or methods to set multiple interdependent values at the same time. Also, if a method has grown to this amount of complexity, it most likely needs to be in its own class anyway.

Demanding consumers to create an instance of classes for no reason

One of the most common arguments is: Why demand that consumers of our class create an instance for invoking this single method, while having no use for the instance afterwards? Creating an instance of a class is a very very cheap operation in most languages, so speed is not an issue. Adding an extra line of code to the consumer is a low cost for laying the foundation of a much more maintainable solution in the future. And finally, if you want to avoid creating instances, simply create a singleton wrapper of your class that allows for easy reuse - although this does make the requirement that your class is stateless. If it's not stateless, you can still create static wrapper methods that handle everything, while still giving you all the benefits in the long run. Finally, you could also make a class that hides the instantiation as if it was a singleton: MyWrapper.Instance is a property that just returns new MyClass();

Only a Sith deals in absolutes

Of course, there are exceptions to my dislike of static methods. True utility classes that do not pose any risk to bloat are excellent cases for static methods - System.Convert as an example. If your project is a one-off with no requirements for future maintenance, the overall architecture really isn't very important - static or non static, doesn't really matter - development speed does, however.

Standards, standards, standards!

Using instance methods does not inhibit you from also using static methods, and vice versa. As long as there's reasoning behind the differentiation and it's standardised. There's nothing worse than looking over a business layer sprawling with different implementation methods.

这篇关于什么时候使用静态类在C#的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆