溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

10個(gè)鮮為人知的C#關(guān)鍵字

發(fā)布時(shí)間:2020-04-08 06:57:15 來(lái)源:網(wǎng)絡(luò) 閱讀:591 作者:蓬萊仙羽 欄目:開(kāi)發(fā)技術(shù)

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 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/yh698w02%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{ }

classClass3Class2{ }

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

 

在正式開(kāi)始之前,我需要先聲明:這些關(guān)鍵字對(duì)于偏向底層的程序員更加耳熟能詳,對(duì)這些關(guān)鍵字不了解并不影響你作為一個(gè)合格的程序員。

  這意味著這些關(guān)鍵字會(huì)讓你在編寫(xiě)程序時(shí)得到更好的代碼質(zhì)量和可讀性

  yield

  yield關(guān)鍵字會(huì)告訴編譯器當(dāng)前的函數(shù)是在一個(gè)循環(huán)內(nèi)部,編譯器會(huì)相應(yīng)生成一個(gè)執(zhí)行它在循環(huán)體內(nèi)部所表示行為的類,yield和return關(guān)鍵字一起用于為枚舉器對(duì)象提供返回值,比如說(shuō):在foreach內(nèi)部的每一次循環(huán)內(nèi),yield關(guān)鍵字用于終止當(dāng)前循環(huán):

   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開(kāi)始,在函數(shù)作用局范圍內(nèi)聲明的變量可以通過(guò)var關(guān)鍵字聲明成隱含類型,隱含類型是強(qiáng)類型,你需要自己聲明隱含類型本地變量,然后編譯器會(huì)幫你決定為某種強(qiáng)類型。

在2.0版本上跑的程序也可以使用var關(guān)鍵字,但是需要你的編譯器是3.0以上版本并且設(shè)置代碼輸出版本為2.0:

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

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

  using()

  定義一個(gè)范圍,在范圍外的對(duì)象將會(huì)被回收:

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

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

  readonly

  readonly關(guān)鍵字是一個(gè)可作用在變量域上的修飾符,當(dāng)一個(gè)變量域被readonly修飾后,這個(gè)變量只可在聲明或者當(dāng)前變量所屬類的構(gòu)造器內(nèi)賦值。

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

  as

  as操作符很像一個(gè)類型轉(zhuǎn)換器,然和,當(dāng)轉(zhuǎn)換無(wú)法發(fā)生時(shí)(譯者按:比如類型不匹配),as會(huì)返回null而不是拋出一個(gè)異常:

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

  在泛型類和泛型方法中產(chǎn)生的一個(gè)問(wèn)題是,在預(yù)先未知以下情況時(shí),如何將默認(rèn)值分配給參數(shù)化類型 T:

  T 是引用類型還是值類型。

  如果 T 為值類型,則它是數(shù)值還是結(jié)構(gòu)。

  給定參數(shù)化類型 T 的一個(gè)變量 t,只有當(dāng) T 為引用類型時(shí),語(yǔ)句 t = null 才有效;只有當(dāng) T 為數(shù)值類型而不是結(jié)構(gòu)時(shí),語(yǔ)句 t = 0 才能正常使用。解決方案是使用 default 關(guān)鍵字,此關(guān)鍵字對(duì)于引用類型會(huì)返回 null,對(duì)于數(shù)值類型會(huì)返回零。對(duì)于結(jié)構(gòu),此關(guān)鍵字將返回初始化為零或 null 的每個(gè)結(jié)構(gòu)成員,具體取決于這些結(jié)構(gòu)是值類型還是引用類型:

T temp = default(T);

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

  global

  在  ::運(yùn)算符前面使用的 global 上下文關(guān)鍵字引用全局命名空間,該命名空間是任何 C# 程序的默認(rèn)命名空間,未以其他方式命名。

class TestClass : global::TestApp { }

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

  volatile

  volatile 關(guān)鍵字表示字段可能被多個(gè)并發(fā)執(zhí)行線程修改。聲明為volatile 的字段不受編譯器優(yōu)化(假定由單個(gè)線程訪問(wèn))的限制。這樣可以確保該字段在任何時(shí)間呈現(xiàn)的都是最新的值。

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

  extern alias

  有時(shí)可能有必要引用具有相同完全限定類型名的程序集的兩個(gè)版本,例如當(dāng)需要在同一應(yīng)用程序中使用程序集的兩個(gè)或更多的版本時(shí)。通過(guò)使用外部程序集別名,來(lái)自每個(gè)程序集的命名空間可以在由別名命名的根級(jí)別命名空間內(nèi)包裝,從而可在同一文件中使用。

 

  若要引用兩個(gè)具有相同完全限定類型名的程序集,必須在命令行上指定別名,如下所示:

  /r:GridV1=grid.dll

  /r:GridV2=grid20.dll

  這將創(chuàng)建外部別名 GridV1 和 GridV2。若要從程序中使用這些別名,請(qǐng)使用 extern 關(guān)鍵字引用它們。例如:

  extern alias GridV1;

  extern alias GridV2;

  每一個(gè)外部別名聲明都引入一個(gè)額外的根級(jí)別命名空間,它與全局命名空間平行,而不是在全局命名空間內(nèi)。因此,來(lái)自每個(gè)程序集的類型就可以通過(guò)各自的、根源于適當(dāng)?shù)拿臻g別名的完全限定名來(lái)引用,而不會(huì)產(chǎn)生多義性。

  在上面的示例中,GridV1::Grid 是來(lái)自 grid.dll 的網(wǎng)格控件,而 GridV2::Grid 是來(lái)自 grid20.dll 的網(wǎng)格控件。

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

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI