为了账号安全,请及时绑定邮箱和手机立即绑定

10个不为人知的C#关键字

标签:
C#

在正式开始之前,我需要先声明:这些关键字对于偏向底层的程序员更加耳熟能详,对这些关键字不了解并不影响你作为一个合格的程序员。

这意味着这些关键字会让你在编写程序时得到更好的代码质量和可读性,enjoy

yield

yield关键字会告诉编译器当前的函数是在一个循环内部,编译器会相应生成一个执行它在循环体内部所表示行为的类,yield和return关键字一起用于为枚举器对象提供返回值,比如说:在foreach内部的每一次循环内,yield关键字用于终止当前循环:

      public classList 
  { 
       //using System.Collections; 
      public static IEnumerable Power(int number, int exponent) 
       { 
           int counter = 0; 
           int result = 1; 
           while(counter++ < exponent) 
           { 
               result = result * number; 
               yield return result; 
           } 
       } 

       static void Main() 
       { 
           // Display powers of 2 up to the exponent 8: 
          foreach (int i in Power(2, 8)) 
           { 
               Console.Write("{0} ", i); 
           } 
       } 
   } 
   /* 
   Output: 
   2 4 8 16 32 64 128 256 
   */

var

自从C# 3.0开始,在函数作用局范围内声明的变量可以通过var关键字声明成隐含类型,隐含类型是强类型,你需要自己声明隐含类型本地变量,然后编译器会帮你决定为某种强类型。

在2.0版本上跑的程序也可以使用var关键字,但是需要你的编译器是3.0以上版本并且设置代码输出版本为2.0:

var i = 10; // implicitly typed
int i = 10; //explicitly typed

using()

定义一个范围,在范围外的对象将会被回收:

using (C c = new C())

{
    c.UseLimitedResource();
}

readonly

readonly关键字是一个可作用在变量域上的修饰符,当一个变量域被readonly修饰后,这个变量只可在声明或者当前变量所属类的构造器内赋值。

as

as操作符很像一个类型转换器,然和,当转换无法发生时(译者按:比如类型不匹配),as会返回null而不是抛出一个异常:

class Class1{ }

classClass2{ }

classClass3: Class2{ }

classIsTest

   {

        static voidTest(objecto)

        {

            Class 1a;

            Class 2b;

            if(o isClass1)

            {

                Console.WriteLine("o is Class1");

                a = (Class1)o;

                // Do something with "a."

            }

            else if (o is Class2)

            {

                Console.WriteLine("o is Class2");

                b = (Class2)o;

                // Do something with "b."

            }

            else

            {

                Console.WriteLine("o is neither Class1 nor Class2.");

            }

        }

        static void Main()

        {

            Class1 c1 = new Class1();

            Class2 c2 = new Class2();

            Class3 c3 = new Class3();

            Test(c1);

            Test(c2);

            Test(c3);

            Test("a string");

        }

    }

    /*

    Output:

    o is Class1

    o is Class2

    o is Class2

    o is neither Class1 nor Class2.

    */

 

default

在泛型类和泛型方法中产生的一个问题是,在预先未知以下情况时,如何将默认值分配给参数化类型 T:

  • T 是引用类型还是值类型。

  • 如果 T 为值类型,则它是数值还是结构。

给定参数化类型 T 的一个变量 t,只有当 T 为引用类型时,语句 t = null 才有效;只有当 T 为数值类型而不是结构时,语句 t = 0 才能正常使用。解决方案是使用 default 关键字,此关键字对于引用类型会返回 null,对于数值类型会返回零。对于结构,此关键字将返回初始化为零或 null 的每个结构成员,具体取决于这些结构是值类型还是引用类型:

T temp = default(T);

 

global

在  ::运算符前面使用的 global 上下文关键字引用全局命名空间,该命名空间是任何 C# 程序的默认命名空间,未以其他方式命名。

class TestClass : global::TestApp { }


volatile

volatile 关键字表示字段可能被多个并发执行线程修改。声明为volatile 的字段不受编译器优化(假定由单个线程访问)的限制。这样可以确保该字段在任何时间呈现的都是最新的值。


extern alias

有时可能有必要引用具有相同完全限定类型名的程序集的两个版本,例如当需要在同一应用程序中使用程序集的两个或更多的版本时。通过使用外部程序集别名,来自每个程序集的命名空间可以在由别名命名的根级别命名空间内包装,从而可在同一文件中使用。

若要引用两个具有相同完全限定类型名的程序集,必须在命令行上指定别名,如下所示:

/r:GridV1=grid.dll

/r:GridV2=grid20.dll

这将创建外部别名 GridV1GridV2。若要从程序中使用这些别名,请使用 extern 关键字引用它们。例如:

extern alias GridV1;

extern alias GridV2;

每一个外部别名声明都引入一个额外的根级别命名空间,它与全局命名空间平行,而不是在全局命名空间内。因此,来自每个程序集的类型就可以通过各自的、根源于适当的名空间别名的完全限定名来引用,而不会产生多义性。

在上面的示例中,GridV1::Grid 是来自 grid.dll 的网格控件,而 GridV2::Grid 是来自 grid20.dll 的网格控件。

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消