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

10 Not So Well Known Keywords in C#

Ok before the flaming start let me state this. These are known to most hardcore programmers and not knowing them doesn’t make you less of a programmer either.

That said these keywords can come in handy and allow for better code quality and readability. Enjoy!

yield

The yield keyword signals to the compiler that the method in which it appears is an iterator block. The compiler generates a class to implement the behavior that is expressed in the iterator block. In the iterator block, the yield keyword is used together with
the return keyword to provide a value to the enumerator object. This is the value that is returned, for example, in each loop of a foreach statement. The yield keyword is also used with break to signal the end of iteration.

example:

  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 returnresult; 
           } 
       }

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


msdn reference: http://msdn.microsoft.com/en-us/library/9k7k7cf0.aspx

var

Beginning in Visual C# 3.0, variables that are declared at method scope can have an implicit type var. An implicitly typed local variable is strongly typed just as if you had declared the type yourself, but the compiler determines the type.

An application running on version 2.0 can also use the var keyword in their code as long as it’s compiled with 3.0 or up and set to output to 2.0.

example:

var i = 10; // implicitly typed

int i = 10; //explicitly typed

msdn reference: http://msdn.microsoft.com/en-us/library/bb383973.aspx

using()

Defines a scope, outside of which an object or objects will be disposed.

example:

using (C c = new C())

{

    c.UseLimitedResource();

}

 

msdn reference: http://msdn.microsoft.com/en-us/library/yh598w02%28VS.80%29.aspx

readonly

The readonly keyword is a modifier that you can use on fields. When a field declaration includes a readonlymodifier, assignments to the fields introduced by the declaration can only occur as part of the declaration or in a
constructor in the same class.

msdn reference: http://msdn.microsoft.com/en-us/library/acdd6hb7%28VS.80%29.aspx

as

The as operator is like a cast operation. However, if the conversion is not possible, as returns null instead of raising an exception. 

example:

class Base

    { public override string ToString()

        {

            return "Base";

        }

    }

    class Derived : Base

    { }

    class Program

    {

        static void Main()

        {

            Derived d = new Derived();

            Base b = d as Base;

            if (b != null)

            {

                Console.WriteLine(b.ToString());

            }

        }

    }

 

msdn reference: http://msdn.microsoft.com/en-us/library/cscsdfbt.aspx

is

Checks if an object is compatible with a given type.

An is expression evaluates to true if the provided expression is non-null, and the provided object can be cast to the provided type without causing an exception to be thrown.

The is keyword causes a compile-time warning if the expression is known to always be true or to always be false, but typically evaluates type compatibility at run time.

The is operator cannot be overloaded.

example:

class Class1{ }

classClass2{ }

classClass3: Class2{ }

classIsTest

   {

        static voidTest(objecto)

        {

            Class1a;

            Class2b;

            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.

    */

msdn reference: http://msdn.microsoft.com/en-us/library/scekt9xw.aspx

default

 

  •  

    n generic classes and methods, one issue that arises is how to assign a default value to a parameterized type T when you do not know the following in advance:
  • Whether T will be a reference type or a value type.
  • If T is a value type, whether it will be a numeric value or a struct.

Given a variable t of a parameterized type T, the statement t = null is only valid if T is a reference type and t = 0 will only work for numeric value types but not for structs. The solution is to use the default keyword, which will return null for reference
types and zero for numeric value types. For structs, it will return each member of the struct initialized to zero or null depending on whether they are value or reference types. For nullable value types, default returns a System.Nullabe<T>, which is initialized
like any struct.

example:

T temp = default(T);

msdn reference: http://msdn.microsoft.com/en-us/library/xwth0h0d.aspx

global

The global contextual keyword, when it comes before the :: operator, refers to the global namespace, which is the default namespace for any C# program and is otherwise unnamed.

example:

class TestClass : global::TestApp { }

msdn reference: http://msdn.microsoft.com/en-us/library/cc713620.aspx

volatile

The volatile keyword indicates that a field might be modified by multiple concurrently executing threads. Fields that are declared volatile are not subject to compiler optimizations that assume access by a single thread. This
ensures that the most up-to-date value is present in the field at all times.

msdn reference: http://msdn.microsoft.com/en-us/library/x13ttww7%28VS.80%29.aspx

extern alias

It can sometimes be necessary to reference two versions of assemblies that have the same fully-qualified type names, for example when you need to use two or more versions of an assembly in the same application. By using an external assembly alias, the namespaces
from each assembly can be wrapped inside root-level namespaces named by the alias, allowing them to be used in the same file.

To reference two assemblies with the same fully-qualified type names, an alias must be specified on the command line, as follows:

/r:GridV1=grid.dll

/r:GridV2=grid20.dll

This creates the external aliases GridV1 and GridV2. To use these aliases from within a program, reference them using the extern keyword. For example:

extern alias GridV1;

extern alias GridV2;

Each extern alias declaration introduces an additional root-level namespace that parallels (but does not lie within) the global namespace. Thus types from each assembly can be referred to without ambiguity using their fully qualified name, rooted in the appropriate
namespace-alias

In the above example, GridV1::Grid would be the grid control from grid.dll, and GridV2::Grid would be the grid control from grid20.dll.

msdn reference: http://msdn.microsoft.com/en-us/library/ms173212%28VS.80%29.aspx

 

Hope this helps!

Hatim

 

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

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

  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 
  */

  MSDN链接:http://msdn.microsoft.com/en-us/library/9k7k7cf0.ASPx

  var

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

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

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

  MSDN链接:http://msdn.microsoft.com/en-us/library/bb383973.ASPx

  using()

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

using (C c = new C()) 
 
{ 
 
  c.UseLimitedResource(); 
 
}

  MSDN链接:http://msdn.microsoft.com/en-us/library/yh598w02%28VS.80%29.aspx

  readonly

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

  MSDN链接:http://msdn.microsoft.com/en-us/library/acdd6hb7%28VS.80%29.aspx

  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. 
 
  */

MSDN链接:http://msdn.microsoft.com/en-us/library/scekt9xw.ASPx

  default

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

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

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

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

T temp = default(T);

  MSDN链接:http://msdn.microsoft.com/en-us/library/xwth0h0d.aspx

  global

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

class TestClass : global::TestApp { }

  MSDN链接:http://msdn.microsoft.com/en-us/library/cc713620.aspx

  volatile

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

  MSDN链接:http://msdn.microsoft.com/en-us/library/x13ttww7%28VS.80%29.aspx

  extern alias

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

 

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

  /r:GridV1=grid.dll

  /r:GridV2=grid20.dll

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

  extern alias GridV1;

  extern alias GridV2;

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

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

  MSDN链接:http://msdn.microsoft.com/en-us/library/ms173212%28VS.80%29.aspx

时间: 2024-09-19 09:14:13

10个鲜为人知的C#关键字的相关文章

苹果创始人乔布斯光环后的10个鲜为人知故事

许多人对乔布斯在科技界的成就并不陌生,但是关于乔布斯其他的事实却鲜为人知,科技网站BusinessInsider根据CNBC最新报道总结了乔布斯的十个鲜为人知的真相,以下为文章全文: 众所周知,乔布斯使得个人电脑业务成为一项蓬勃的产业,直到现在,其公司还在不断推陈出新各种受欢迎的产品.但是乔布斯在生活中许多细节,包括和苹果一起经历过的大起大落却鲜为人知,我们特地根据CNBC"Titans"的最新报道总结出了其鲜为人知的10个真相. 1.在1974年在Atari工作时,乔布斯试图使用最小

Java多线程初学者指南(10):使用Synchronized关键字同步类方法

要想解决"脏数据"的问题,最简单的方法就是使用synchronized关键字来使run方法同步,代码如下: public synchronized void run() { } 从上面的代码可以看出,只要在void和public之间加上synchronized关键字,就可以使run方法同步,也就是说,对于同一个Java类的对象实例,run方法同时只能被一个线程调用,并当前的run执行完后,才能被其他的线程调用.即使当前线程执行到了run方法中的yield方法,也只是暂停了一下.由于其他

PHP里10个鲜为人知但却非常有用的函数

 PHP里有非常丰富的内置函数,很多我们都用过,但仍有很多的函数我们大部分人都不熟悉,可它们却十分的有用.这篇文章里,我列举了一些鲜为人知但会让你眼睛一亮的PHP函数. levenshtein() 你有没有经历过需要知道两个单词有多大的不同的时候,这个函数就是来帮你解决这个问题的.它能比较出两个字符串的不同程度. 用法: $str1 = "carrot"; $str2 = "carrrott"; echo levenshtein($str1, $str2); //O

Leopard操作系统10个鲜为人知的秘密

Mac OS X操作系统每次升级时,最让我感兴趣的都是那些细小之处,这些才是能够提高OS X可用性的关键所在,也是在人们对那些招牌般的新功能的关注渐渐平息后,我更觉得有意思的地方. 想不注意到Mac OS X 10.5 Leopard 的一些大改进是很难的--时间机器,Spaces空间,Stacks,封面秀,桌面外观和感受上的变化等,但每次OS X操作系统升级时,最让我感兴趣的都是那些细小之处.这些才是能够提高OS X可用性的关键所在,也是在人们对那些招牌般的新功能的关注渐渐平息后,我更觉得有意

Ubuntu One 的10个鲜为人知的功能

尽管 Ubuntu One 看上去像一个仅支持 Ubuntu 文件同步服务,但实际上它可以在 Windows,Android,iOS 和网页上使用.而且,Ubuntu One 提供了5GB的免费存储空间. (图片来自: http://kryuko.deviantart.com/art/Ubuntu-One-Icon-332840346 ) 根据 howtogeek.com 的介绍,用户通过 Ubuntu One 可以在线共享文件或目录,推送音乐到手机,在所有的设备上同步已安装的应用等等.下面我们

排名前10位SEO误区

SEO误区对于很多朋友都知道,这里湖南seo整理了一下前十位的一些错误的操作方式,希望能帮助到大家.   seo排名前十位的误区 1.针对错误的关键词 在关键词上,很多人都会犯错,即使是非常有经验的SEO专家.人们选择的关键字的时候,在他们的头脑里肯定会把描述自己的网站放在第一位,但是很多词对客户来说基本上是不会去搜索的.举例来说,如果你有个关键词是"关系"的网站,你可能会发现,"关系指南"这个词却不能给你带来流量!即使它有"关系"这个关键字,而

volatile关键字的说明以及测试

volatile关键字是一种类型修饰符,用它声明的类型变量表示可以被某些编译器未知的因素更改,比如:操作系统.硬件或者其它线程等.遇到这个关键字声明的变量,编译器对访问该变量的代码就不再进行优化,从而可以提供对特殊地址的稳定访问. 使用该关键字的例子如下: int volatile nVint; 当要求使用volatile 声明的变量的值的时候,系统总是重新从它所在的内存读取数据,即使它前面的指令刚刚从该处读取过数据.而且读取的数据立刻被保存. 例如: volatile int i=10; in

线程-volatile 关键字 作用结果求解惑

问题描述 volatile 关键字 作用结果求解惑 public class testVolatile { private int i = 0; // a线程调用 public void foo1() { try { while (true) { Thread.sleep(10); System.out.println(""第一个:"" + i); i++; } } catch (InterruptedException e) { // not to do; } }

[原创]侯佩日记摘录之一:2000年10月x日

[原创]侯佩日记摘录之一:2000年10月1+x日        关键字:侯佩,日记,摘录之一        四周是极度的黑,我还得以不死,张狂的窥探这个世界.坚强的意志弥补了我即将衰变退化的躯干,我小心的寻找着,搜索着- 终于,我发现了,一种极强的本能欲望驱使着我,暴露的青筋,跳动着的液体,我贪婪的吮吸着,吮吸着,我只有获得才能生存,而思考 使我谨慎和封闭.我没有沟通的对象,更多的时间是沉眠和幻想,而黑暗却滋养着我的敏锐,沉侵在美妙的黑宙中,使我更容易思考,而又越发的丑陋起来,连我也开始恶心自