zoukankan      html  css  js  c++  java
  • C# 2.0 之 static class

    C# 2.0 之 static class

    看看什么是 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 = abstract 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 中很容易有两

    个类型死锁的情况发生,在编写代码的时候一定要想清楚。
     
    我为什么要使用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 在 语义 上显得更加优美。



    至少,一看就能明白,不用在尝试实例化 Utility 失败以后去寻找出错的原因。



    或许很牵强,我总是会有这种不切实际的苛求。但 ms 还是满足了我的苛求。

    ------------------------------
    反编译一下,会了解其实现机制。
    原来编译器将该类声明为 abstract sealed,自然不能被继承被实例化了。
    但是C#编译器并不允许我们在代码中直接声明一个abstract sealed类型,下面的代码无法通过编译。
    静态类的限制

    1. 静态类不能有实例构造器。
    2. 静态类不能有任何实例成员。
    3. 静态类上不能使用abstract和sealed修饰符。
    4. 静态类默认继承自System.Object,不能显式指定任何其他基类。
    5. 静态类不能指定任何接口实现。
    6. 静态类的成员不能有protected或者protected internal访问保护修饰符。
  • 相关阅读:
    主线程和子线程的区别
    正则表达式 之 常用实例
    Asp.Net 之 未能加载文件或程序集 system.web.extensions 解决方法
    .Net 与 Java 的服务接口相互调用
    C# 之 SqlConnection 类
    ADO.Net 之 数据库连接池(一)
    C# 之 DataReader 和 DataSet 的区别
    Asp.Net 之 缓存机制
    IIS 之 失败请求跟踪规则
    IIS 之 HTTP错误信息提示
  • 原文地址:https://www.cnblogs.com/dudu837/p/1384366.html
Copyright © 2011-2022 走看看