您的位置:威尼斯官方网站 > 威尼斯正规官网 > 威尼斯官方网站有关的文章似乎无外乎两个方面

威尼斯官方网站有关的文章似乎无外乎两个方面

发布时间:2020-01-04 04:03编辑:威尼斯正规官网浏览(134)

    [自序]

    固然Microsoft Visual Studio .NET 二〇〇七(过去周边叫Visual Studio .NET 2003)每每延期其公布日期,但成千上万开拓者对其的猜忌以至各类媒体对其各省点的“揭露”也好似已经浸润了互连网。但与C#有关的稿子就如无外乎七个地点:VS.NET 2007 IDE天性、介绍C# 2.0中引进的“四大特点(泛型、佚名形式、迭代器和不完全类型)”。对IDE的研究自己不想谈了,微软便是微软,他的窗口应用程序总是没得说的。而就语言自己的改良来讲,在自己听完了AndersHejlsberg在Microsoft Professional Developers Conference 2004(2001.10, Los Angeles, CA)上的解说后,开采除了那四大特点之外,还会有部分鲜为人知的特点,以至在微软官方的文书档案《C# Language Specification Version 2.0》中都从未有过提到。而这么些特色却更是提升了言语的逻辑性。于是本人编写了大批量实在程序探究了那几个特点,终于著花费文。本筹算公布在《CSDN开辟高手》杂志上的,可无奈水平有限,只好留在此个角落里班门弄斧了。希望能够对那几个对C#语言有着浓郁兴趣的相爱的人有个别推推搡搡。

    ——lover_P 于北工业大学1号楼221寝室

    [修改装订表明]

    2004-08-24
    第1回修正。校订了汪洋的错别字和文法错误。增多了对global限制符的介绍。
    [正文]

    微软在其将在分娩的C#2.0(Visual C# Whidbey)中,增添了众多令技师感觉振作激昂的新特征。除了泛型(Generic)、迭代器(Iterator)、无名情势(Anonmynous)和缺损类型(Partial Type)等根本的改良,还对现成的语法细节实行了十分的大的改革,比相当大地惠及了.NET框架程序设计的做事,何况一发进步了C#语言唯有的高逻辑性。在本文中,小编将向大家介绍一下那几个改进。(文中C#替代的是C#1.2及此前的版本,而C#2.0代表的是微软从不正式推出的C# Whidbey;小说中的全部代码均在版本号为8.00.30703.4的C#编写翻译器下进展了测量检验,标有*的不当音信得自版本号为7.10.3052.4的C#编译器。)

    [内容]

    静态类
    品质的可访问性限定
    取名空间外号
    global限定符
    编写翻译器指令
    固化大小缓冲区
    参照他事他说加以考察文献  

    静态类
    使用C#进行.NET框架程序设计的人应该都了然,不可能将三个类注明为静态的。譬如,上边包车型客车类表明:

    public static class A {
    static int i;
    }

    在C#中是不著见效的,当我们尝试编写翻译这段代码时会获得下边的编写翻译错误*:

    error CS0106: 修饰符“static”对该项无效

    鉴于不能用static修饰符修饰贰个类,大家在类中三回九转能够既证明静态成员又声称实例成员。那的确会推动十分的大的灵活性。可是,如若我们期望三个类是静态的,也等于可望免强须要这几个类中的全部成员都应有为静态的,就不可能了,唯生龙活虎能做的便是本身在乎将具有的分子声称为static。当我们忘记对四个本应是静态的积极分子运用static修饰符(固然那是一个“低端错误”,但仍然有不小可能率产生)时,将会爆发难以逆料的不当。最根本的是,对于贰个逻辑上的静态类(全数成员均运用static修饰符实行宣示的类),我们还能够申明该类的多个变量并使用new操作符发生该类的实例!那鲜明不是大家所希望的。

    而在C#2.0中,则提供了静态类这一定义,允许static修饰符对类进行修饰,下边包车型客车代码能够通过编写翻译。假诺贰个类注明中包蕴了static修饰符,那么这一个类中的全部成员将被勒迫必要评释为静态的。那个时候,如若我们有目的在于类中声称实例成员或是异常的大心忘记了成员声称中的static修饰符,如上面代码所示:

    public static class A {
    int i;
    }

    则编写翻译器会报告错误:

    error CS0708: 'A.i': cannot declare instance members in a static class

    况且,假设大家评释该类的变量或是试图创设该类的多个实例时,如下边包车型大巴代码:

    public class Test {
    A a; // error CS0723
    void Foo() {
    a = new A(); // error CS0712
    }
    }

    则会收获上面包车型客车五个编写翻译错误:

    error CS0723: Cannot declare variable of static type 'A'
    error CS0712: Cannot create an instance of the static class 'A'

    很显然,C#2.0中对静态类的协理宏大程度地幸免了我们在书写程序中的意外失误,尤其是提升了静态类的逻辑性,提升了代码的可读性。

    质量的可访谈性限定
    C#为我们提供了极其有益的特性定义,使得我们能够像访谈类的国有变量成员这样访谈类的质量,但还足以同不时候拿到像访谈函数那样的安全性。但是,C#只允许属性的安装动作(set{...})和收获动作(get{...})具备相似的可访谈性(由属性注脚中的public、internal和private等修饰符钦命)。那么,当大家希望允许从其它程序集中的类获取八个特定类的属性,但只同意此类所在的程序集或该类的个人成员工夫设置该属性时,大家只可以将以此本性注明为国有且只读(即接受public修饰符注明但独有get{}域),而里边的或个体的成员只好通过安装与该属性相关的中间或个体的变量成员的值来成功质量的设置工作:

    public class A {
    int _intValue; // 与品质相关的叁个int类型的分子变量

    // 公有且只读的属性,允许任何类获取该属性的值:
    public int Value {
    get { return _intValue; }
    }

    // 上面包车型地铁办法必要安装方面包车型大巴性格,
    // 但只可以通过拜谒私有成员变量来产生,
    // 并且要其它进行错误管理
    private void SomeMethod() {
    int i;
    // ......
    // 上面包车型地铁if-else语句仅用来设置属性值:
    if(0 < i && i < 10) {
    _intValue = i;
    }
    else {
    // 错误管理
    }
    }
    }

    很声名远扬,这种做法是老大艰巨的。借使在多少个地点转移了成员变量的值会使代码变得冗长不可读,还很有十分的大可能率会时有发生错误,举个例子该类有别的一个主意:

    private void AnotherMethod() {
    int i;
    // ......
    // 上面包车型客车if-else语句仅用于安装属性值,
    // 但其对i的间隔检查测验发生了不当
    if(0 < i && i <= 10卡塔尔(قطر‎ { // 注意这里的 <= 运算符
    _intValue = i;
    }
    // 况且未有进展错误管理
    // ......
    }

    上面的点子对就要赋给个人变量成员的值的检查区间是大谬不然的,这种张冠李戴是很有超级大可能率产生的。大器晚成旦调用了那些点子,_intValue很有希望具有错误的值,而访谈了Value属性的表面程序集将会现出逻辑错误。这种不当的减轻是生龙活虎对风度翩翩费力的。並且,就算叁个小组中的别的成员负担规划相仿程序集中其余的类,必要她们在方式中书写如此大方的代码并要进行不当检查是不相同房的。

    理所当然,咱们恐怕会想到将这种装置属性值的办事置于二个里面方法中汇聚开展:

    // 程序集内部的类或该类的个人成员通过
    // 下边包车型大巴内部方法对上边的品质举办安装职业
    internal void _setIntValue(int newValue) {
    if(0 < newValue && newValue < 10) {
    _intValue = newValue;
    }
    else {
    throw new System.InvalidArgumentException (
    “The new value must greater than 0 and less than 10”
    );
    }
    }

    // 下边的法子须求对上述天性举行安装
    private void SomeMethod() {
    int i;
    // ......
    _setIntValue(iState of Qatar; // 通过调用内部方法开展
    }

    如此那般做纵然防止了逻辑错误的产出(起码使出现了错误时的解决专门的学问变得轻便),但其可读性照旧倒霉好,非常是逻辑性相当糟糕,与“属性”自个儿的意思天冠地屦。

    然而C#2.0同意大家对质量的get{}和set{}域分别安装可访问性,咱们能够将下面的代码轻松地撰写:

    public class A {
    int _intValue; // 与特性相关的一个int类型的积极分子变量

    // 公有的习性,
    // 允许任何类获取该属性的值,
    // 但独有程序集内部的类和该类中的私有成员
    // 能够设置属性的值
    public int Value {
    get {
    return _intValue;
    }
    internal set {
    if(0 < value && value < 10) {
    _intValue = value;
    }
    else {
    throw new System.InvalidArgumentException (
    “The new value must greater than 0 and less than 10”
    );
    }
    }
    } // property

    // 上边包车型地铁点子必要对上述特性实行设置
    private void SomeMethod() {
    int i;
    // ......
    Value = i;
    }
    }

    尤为在先后聚集的其它类的分子中拜见该属性时一定平价:

    // 这是同三个先后集中此外的叁个类:
    public class B {
    public A SomeMethod() {
    A a = new A();
    a.Value = 8; // 这里对品质进行设置,方便!
    return a;
    }
    }

    能够见到,可以对品质的获取和安装操作分别安装可访谈性节制十分的大地增加了C#程序的可读性和语言逻辑性,写出的程序也享有更加强的可维护性。

    取名空间小名
    在C#中,使用类(如宣称成员变量或调用静态方法等)的时候要求内定类的一点一滴名称,即命名空间前缀加类的名字。假如大家要在调节台上打字与印刷“Hello, world!”,则须求写:

    System.Console.WriteLine(“Hello, world!”);

    中间,System是命名空间,Console是类的名字,WriteLine(卡塔尔(قطر‎是大家要调用的措施。

    像这种类型的要求鲜明会使代码变得特别冗余。由此,C#为大家提供了using关键字(指令)。通过使用using指令,我们得以向编写翻译器钦定朝气蓬勃多元命名空间,当程序中现身了类名字时,编写翻译器会活动到那几个命名空间中搜索那么些类。由此,上边包车型客车代码能够创作:

    using System;
    // ......
    public class Test {
    public static void Main() {
    Console.WriteLine(“Hello, world!”);
    }
    }

    呵呵,那不正是精华的“Hello World”表率么?很猛烈,这种写法方便得多,能够十分大地进步开拓功用。

    不过,四个命名空间中很恐怕具备同名的类,而作者辈刚刚要求用到那一个同名的类。这种情景会平日爆发。例如在.net框架类库中就存在有三个Timer类:System.Timer.Timer、System.Threading.Timer和System.Windows.Forms.Timer。我们很只怕须求多个Timer类:八个System.Timer.Timer用于在后台以向来的大运间距检查应用程序或系统状态,叁个System.Windows.Forms.Timer用于在客户分界面中显示轻松动画。这时候,就算大家使用了using指令,大家如故供给在这一个类现身时增进命名空间:

    using System.Timer;
    using System.Windows.Forms;
    // ......
    public class MainForm : Form {
    System.Timer.Timer CheckTimer;
    System.Windows.Forms.Timer AnimateTimer;
    // ......
    }

    这么的次第依然显得冗长。

    在C#2.0中,using指令的应用获得了扩展,大家得以利用using指令来为命名空间钦点二个外号。当大家供给引用这几个命名空间时,可以归纳地运用它的别称。为命名空间创造三个外号时,我们应用using指令的扩展用法:using Alias = Namespace,就可以为命名空间Namespace钦赐叁个别称Alias。而别称和命名空间的使用办法完全相像。当我们援引七个命名空间中的类型的时候,只须要在命名空间后边加一个圆点“.”再跟上类别名称就能够;而引用三个小名所代表的命名空间中的类型时,写法是完全一样的。那么,上边包车型地铁事例能够编写:

    using SysTimer = System.Timer;
    using WinForm = System.Windows.Forms;
    // ......
    public class MainForm : WinForm.Form {
    SysTimer.Timer CheckTimer; // 与命名空间的选拔完全近似
    WinForm.Timer AnimateTimer;
    // ......
    }

    笔者们能够看来,那样的代码要轻易得多。

    global限定符
    在C#2.0原先,在利用命名空间时还会有多少个拾叁分微小的难题。那正是C#命名空间的寻找方法。考虑下边那些例子:

    using System;

    namespace MyNamespace {
    namespace System {
    public class MyConsole {
    public void WriteLine(String str) {
    System.Console.WriteLine(str卡塔尔国; // 注意那蓬蓬勃勃行!
    }
    }
    }
    }

    那边自身在大团结的命名空间内注脚了一个System命名空间,并在中间模拟了决定台类。小编盼望它经过调用System.Console类的不二秘技来效仿调节台的行事。那个程序片断是从未语法难点的,当仍旧不可能因而编译。其首要性原因是C#的命名空间成效域和平日变量的功用域准则雷同,总是查找这段时间的注明,而且此中宣称能够覆盖外界表明。因而,这段代码中标有注释的一站式在编写翻译的时候编写翻译器会提醒找不到类MyNamespace.System.Console——它试图在自己自个儿的命名空间里找System.Console类!

    在C#2.0原先,这些难点对于类库的设计者来说是万分胸口痛的。唯后生可畏的消除方法就是尽量在友好的命名空间内不应用全局命名空间中的名字。然而,由于类库开拓者众多,难免会现身相像的情形;並且,那样做还有只怕会招致既是在自身的命名空间中也无法利用可读性高而又轻易的名字,那确实加害了语言的逻辑性和简洁性。

    然而,C#2.0引进了global关键字,允许大家从全局选择命名空间。下边这几个图示从.net命名空间的结构表达了global关键字的身价:


    图示1:global关键字的地点
    在C#1.x中:

    +++ Who's the root? +++
    |
    +- System (namespace)
    | |
    | +- Console (class)
    | +WriteLine (method)
    | +- Int32 (struct)
    | +- ...
    |
    +- MyNameSpace (namespace)
    |
    +- System ([sub]namespace)

    • MyConsole (class)

    在C#2.0中

    global (!!!ROOT!!!)
    |
    +- System (namespace)
    | |
    | +- Console (class)
    | +WriteLine (method)
    | +- Int32 (struct)
    | +- ...
    |
    +- MyNameSpace (namespace)
    |
    +- System ([sub]namespace)

    • MyConsole (class)

    那样一来,大家就能够通过行使global关键字轻易地消亡命名空间的冲突难点。上边包车型地铁例子也就可以知道重写为:

    using System;

    namespace MyNamespace {
    namespace System {
    public class MyConsole {
    public void WriteLine(String str) {
    global.System.Console.WriteLine(str卡塔尔国; // 注意那风华正茂行!
    }
    }
    }
    }

    编写翻译器指令
    在大家调节和测量检验C#程序时,平日会声澳优(Ausnutria Hyproca卡塔尔国些有的时候变量用来监测程序状态,并在调节和测验实现后将这么些注明删除。而当大家评释了这么的一时半刻变量,在调节和测验进程中却未有动用的时候,大家普通会拿走大量的如:

    warning CS0168: The variable 'exp' is declared but never used

    的警示。但是,大家很了然那样的警戒是无害的。同样,比比较多别样时候咱们也会收获部分告诫,但大家一定要从大气的无害的警报中寻找我们需求的荒唐音讯。

    然而,C#2.0为大家提供了一条新的编写翻译器指令:pragma warning,使得大家能够在风华正茂段代码中明确命令禁绝部分我们承认无毒的警示(通过点名警示的号子)。此前,这种工作只可以由特定的编写翻译器选项(举例Microsoft Visual C#编写翻译器的/nowarn)或相应的IDE选项(如Microsoft Visual Studio .NET 二〇〇三中的项目属性页中的相应选项)来达成。何况,通过编译蒙受来隐蔽警示将促成在编写翻译整个项目或任何源文件的历程中负有相应的警告都会被隐形。如果我们唯有理解在某三个代码块中三个警戒是没有害的,但对此代码的别的一些,我们仍旧期待观察那么些警告消息时,这种做法就不可能了。此时,我们独有经过pragma warning指令来命令编译器仅仅掩盖某二个代码块中相应的告诫。我们能够用下列代码来防止发生上边的例子中所述的“未利用参数”的警示:

    public class Test {
    public void SomeMethod() {
    // 上面包车型地铁编译器指令幸免了“未采纳参数”的告诫:
    #pragma warning disable 0168
    int tempStatus;
    // ......
    // 下边包车型客车编写翻译器指令重新允许爆发“未使用参数”的告诫:
    #pragma warning restore 0168
    }
    }

    与此相类似,当编译器编写翻译SomeMethod(State of Qatar方法时,将不会发出上述的“未选拔参数”的警示,但在编写翻译其余代码段时,依然会时有产生该警报,因为我们用#pragma warning restore指令重新打开了该警示。

    稳定大小缓冲区
    终极,除了上述的有个别特色外,C#2.0还提供了“固定大小缓冲区(Fixed Size Buffers)”的新特色。即像C语言那样能够在结构中声雅培(Abbott卡塔尔(قطر‎个牢固大小的数组,那通过System.Runtime.CompilerServices.FixedBufferAttribute属性和Fixed关键字落到实处(参见仿照效法文献第26页):

    [System.Runtime.CompilerServices.FexedBuffer]
    public struct Buffer {
    public fixed char Buffer[128];
    }

    但鉴于自己所使用的编译器还没帮忙这一表征,手头又从不相应的资料,在这里就不做牵线了。

     

    以上是自个儿对C#2.0中除去泛型、迭代器、无名格局和分局类型等关键改良之外的部分对现存个性开展的改革的简约介绍。这个改良看起来很稍稍,却相当大程度地拉长了C#语言的逻辑性,使得大家能够写出更为优秀且可维护性更加强的代码。笔者的介绍是特别轻易的,以至也许有不当,希望我们指教。(联系方式:lyb_dotNET@hotmail.com)

    本文由威尼斯官方网站发布于威尼斯正规官网,转载请注明出处:威尼斯官方网站有关的文章似乎无外乎两个方面

    关键词: