Static Classes and Static Class Members

Static Classes and Static Class Members (C# Programming Guide)

Visual Studio 2005
286 out of 387 rated this helpful - Rate this topic

Static classes and class members are used to create data and functions that can be accessed without creating an instance of the class. Static class members can be used to separate data and behavior that is independent of any object identity: the data and functions do not change regardless of what happens to the object. Static classes can be used when there is no data or behavior in the class that depends on object identity.

A class can be declared static, indicating that it contains only static members. It is not possible to create instances of a static class using the new keyword. Static classes are loaded automatically by the .NET Framework common language runtime (CLR) when the program or namespace containing the class is loaded.

Use a static class to contain methods that are not associated with a particular object. For example, it is a common requirement to create a set of methods that do not act on instance data and are not associated to a specific object in your code. You could use a static class to hold those methods.

The main features of a static class are:

Creating a static class is therefore much the same as creating a class that contains only static members and a private constructor. A private constructor prevents the class from being instantiated.

The advantage of using a static class is that the compiler can check to make sure that no instance members are accidentally added. The compiler will guarantee that instances of this class cannot be created.

Static classes are sealed and therefore cannot be inherited. Static classes cannot contain a constructor, although it is still possible to declare a static constructor to assign initial values or set up some static state. For more information, see Static Constructors (C# Programming Guide).

Suppose you have a class CompanyInfo that contains the following methods to get information about the company name and address.

C#
class CompanyInfo
{
    publicstring GetCompanyName() { return"CompanyName"; }
    publicstring GetCompanyAddress() { return"CompanyAddress"; }
    //...
}

These methods do not need to be attached to a specific instance of the class. Therefore, instead of creating unnecessary instances of this class, you can declare it as a static class, like this:

C#
staticclass CompanyInfo
{
    publicstaticstring GetCompanyName() { return"CompanyName"; }
    publicstaticstring 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.

A static method, field, property, or event is callable on a class even when no instance of the class has been created. If any instances of the class are created, they cannot be used to access the static member. Only one copy of static fields and events exists, and static methods and properties can only access static fields and static events. Static members are often used to represent data or calculations that do not change in response to object state; for instance, a math library might contain static methods for calculating sine and cosine.

Static class members are declared using the static keyword before the return type of the member, for example:

C#
publicclass Automobile
{
    publicstaticint NumberOfWheels = 4;
    publicstaticint SizeOfGasTank
    {
        get
        {
            return 15;
        }
    }
    publicstaticvoid Drive() { }
    publicstaticevent EventType RunOutOfGas;

    //other non-static fields and properties...
}

Static members are initialized before the static member is accessed for the first time, and before the static constructor, if any is called. To access a static class member, use the name of the class instead of a variable name to specify the location of the member. For example:

C#
Automobile.Drive();
int i = Automobile.NumberOfWheels;

Here is an example of a static class that contains two methods that convert temperature from Celsius to Fahrenheit and vice versa:

C#
publicstaticclass TemperatureConverter
{
    publicstaticdouble CelsiusToFahrenheit(string temperatureCelsius)
    {
        // Convert argument to double for calculations.double celsius = System.Double.Parse(temperatureCelsius);

        // Convert Celsius to Fahrenheit.double fahrenheit = (celsius * 9 / 5) + 32;

        return fahrenheit;
    }

    publicstaticdouble FahrenheitToCelsius(string temperatureFahrenheit)
    {
        // Convert argument to double for calculations.double fahrenheit = System.Double.Parse(temperatureFahrenheit);

        // Convert Fahrenheit to Celsius.double celsius = (fahrenheit - 32) * 5 / 9;

        return celsius;
    }
}

class TestTemperatureConverter
{
    staticvoid Main()
    {
        System.Console.WriteLine("Please select the convertor direction");
        System.Console.WriteLine("1. From Celsius to Fahrenheit.");
        System.Console.WriteLine("2. From Fahrenheit to Celsius.");
        System.Console.Write(":");

        string selection = System.Console.ReadLine();
        double F, C = 0;

        switch (selection)
        {
            case"1":
                System.Console.Write("Please enter the Celsius temperature: ");
                F = TemperatureConverter.CelsiusToFahrenheit(System.Console.ReadLine());
                System.Console.WriteLine("Temperature in Fahrenheit: {0:F2}", F);
                break;

            case"2":
                System.Console.Write("Please enter the Fahrenheit temperature: ");
                C = TemperatureConverter.FahrenheitToCelsius(System.Console.ReadLine());
                System.Console.WriteLine("Temperature in Celsius: {0:F2}", C);
                break;

            default:
                System.Console.WriteLine("Please select a convertor.");
                break;
        }
    }
}

看看什么是 static class 吧,很久以前我就为不能声明一个 abstract sealed class

而苦恼不已,我在 CSDN 上曾经提出过这个问题,可是并没有获得共鸣。我得到的回复

是这样的:

abstract sealed一起用?定义abstract的目的就是抽象基类,seal表示不能继承的

实体类,完全是两回事,怎么可能一起用呢?

abstract表明必须要被继承,sealed表明不可以被继承,这两个是矛盾的,怎么可以一

起用呢。

通过查看 IL 代码,我们会发现 static class 实际上就是 abstract sealed class

只不过编译器在编译时顺便对 static class 的成员修饰符进行检查而已。

让我们再来猜测一下 MS 开发人员的想法:他们的目的是想获得 abstract sealed

class 的效果,但却为语义上的矛盾而苦恼不已,大家想获得一个优美的解决方式,于

是就为 C 2.0 新增了一个 static 关键字,完美的解决了这个问题。

也许有人会问:为什么不是 static class + static member limit

而要加上 sealed 的限制呢?理由是继承一个只有 static 成员的类和重新写一个类完

全没有区别。为什么这么说呢?因为 static 必然是not virtual,继承它又能有什么

用呢?

static class 还有一个限制,那就是只能从 System.Object 继承,为什么会有这个限

制,理由和上面差不多。

每每提到 static 关键字,我就想起了 static constructor,感谢 MS 的开发人员提

供了这么好的一个特性。但是 C 提供了 static constructor 却没有提供 static

destructor,不过在 Applied Microsoft .NET Framework Programming 一书中

Jeffery Richter 给我们提供了一个办法就是通过 System.AppDomain.DomainUnload

事件去达到同样的效果。

使用 static constructor 要注意的就是这里抛出任何异常都会导致该类型在重新加载

AppDoamin 之前不再可用,所以要加倍小心,另外 static contructor 中很容易有两

个类型死锁的情况发生,在编写代码的时候一定要想清楚。

--

刘敏

Rustle Liu

http://ms.mblogger.cn/rustle/

-------------------

我为什么要使用static class

其实,static class 给了我们 abstract sealed class 同样的效果,而我为什么想要得到 abstract sealed 的效果呢,以下是我之前产生这个想法的原因,至于 ms 引入 static class 真正的原因,我就不知道了。

假设我要写一个简单的func,用来处理字符串,它的功能就是给传入的字符串加上单引号并将已有的单引号替换掉:

public String Quote(String Str)

{

return "'" + Str.Replace("'","''") + "'";

}

这个函数很简单,可是在 C# 中,我把它放在什么地方呢?它必须是某个类的一员:

public class Utility

{

public String Quote(String Str){}

}

1、我不希望它每次处理字符串的时候还要创建一个 Utility 对象实例,所以 Quote 函数必须是 static 的。

2、既然 Utility 类只提供这样类似的 static 方法,所以它没有必要被实例化。

3、我不希望有人继承 Utility 类,这是一件无意义的事情,因为它的成员都是 static 的。

我希望能写这样的代码:

public abstract sealed class Utility

{

public static String Quote(String Str){}

}

可是它并不能通过编译,C# 2.0中仍然不能,但是我可以用 static 来代替 abstract sealed

也许你会说这样也可以:

public sealed class Utility

{

private Utility(){}

public static String Quote(String Str){}

}

这样确实也可以,也许我的理由很牵强,但是我总觉得,这个不是那么优美,感觉是用了一个技巧。

static class 在语义上显得更加优美

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值