zoukankan      html  css  js  c++  java
  • 18个不常见的C#关键字,您使用过几个?

    1、__arglist

        让我们先从__arglist开始。 __arglist是用来给方法传送参数。通常我们是通过函数头部指定的参数列表给方法传递参数的。如果我们想要给方法传递一组新的参数,我们需要重载方法。如果我们想要传递的参数数量不确定,我们需要使用param数组。我们为什么要使用__arglist,因为上面两种方法,存在的下面问题:

    a、如果我们使用方法重载,一旦要传递一组新的参数,我们都要增加一个新的函数重载。

    b、如果我们用param数组,参数类型必须相同或者使用param对象数组。

    __arglist能解决上面的问题。你可以传递任何参数给函数,可以是任何类型,我们可以使用简单的步骤分析每个参数。

    让我们先看下下面代码:

    1 public int paramLength(__arglist)
    2 {
    3           ArgIterator iterator = new ArgIterator(__arglist);
    4           return iterator.GetRemainingCount();
    5 }

    如果我使用下面代码调用该函数

    1 int x = this.paramLength(__arglist(49,34,54,6,"Manimoy")); // returns 5 

    将被返回5给变量x。这是因为我们给这个方法传递了5个参数。我们可以访问每个参数,如: 

    1 TypedReference tf = iterator.GetNextArg();
    2 TypedReference.ToObject(tf)

    每次调用GetNextArg,GetRemainingCount将减1,直到遍历完迭代器的每个对象。

    2、__refvalue 

    另一个有趣的关键字是__refvalue。它是用来获取一个引用对象的的值。你可以用来从TypedReference对象中获得实际对象。这需要两个参数,第一个就是TypedReference对象和另一个是转换的类型。看看下面代码:

    1 int tfValue = __refvalue(tf, int); 

    3、__makeref

    __makeref将使从对象中找出TypedReference对象。这跟_refvalue刚刚相反。请看下面的代码:

    1 string name = "Ayan";
    2 TypedReference tf = __makeref(name);

    4、 __reftype

    __reftype是用来从TypedReference类型的对象获得类型。看下面代码所示:

    1 Type t = __reftype(tf);
    2 if(t.ToString().equals("System.String"))
    3 string str = __refvalue(t,string); 

    注:虽然我在所有的C#版本中发现上面这些关键字,但我没在工作中使用它。在未来版本的C#可能不存在这些关键字,所以是否使用看你自己的风险。

    5、Yield

        Yield出现在.NET 2.0中,使用Yield将以枚举数对象值的形式返回,yield 语句只能出现在iterator 块中,该块可用作方法、运算符或访问器的体。在以下代码中,我构建了一个名字列表,将返回长度小于5的名字列表,遇到yield break语句返回。

     1 List<string> lst = new List<string>();
     2 lst.Add("Abhishek");
     3 lst.Add("Abhijit");
     4 lst.Add("Manimoy");
     5 lst.Add("Raj");
     6 lst.Add("Ayan");
     7 lst.Add("MacMillanRojer");
     8 lst.Add("Rizzuto");
     9 foreach (string x in lst)
    10 {
    11    if (x.Length > 12// Breaks on MacMillanRojer
    12      yield break;
    13    else if (x.Length > 5// Only returns those which are having length >5
    14      yield return x;
    15    else continue;
    16 }
    17  

    其实,yield return x 将判断每个元素,并创建了满足条件所有的元素的enumerable(length> 5)。
    break语句将终止循环,并返回现有创建好的枚举。

    6、 Fixed

    另一种不常见的关键字是Fixed,它只能在不安全的C#代码块中使用。Fixed语句在个固定的内存地址设置一个指针,它不会被移动到任何地方,即使执行了垃圾收集线程。让我们来看看下面的代码:

    1  int[] a = new int[] { 123 };
    2 fixed (int* pt = a)
    3 {
    4    int* c = pt;
    5    MessageBox.Show("Value : " + *c);
    6    // This will fix the variable totally so that it will
    7    // not be moved when Garbage collector is invoked. 
    8 }

    在这里,指针c和pt被分配相同的位置。Fixed通常会花销一些资源。实际上它妨碍垃圾收集的正常进程。因此,实际中应该避免使用 fixed语句。

    7、Checked / Unchecked 

        另一个名为checked的关键字是用来控制算术溢出的情况。当算术运算溢出时,Checked关键字抛出OverflowException异常。

        看下这段代码:

    1 int x = int.MaxValue;
    2 int y = int.MaxValue;
    3 int z = checked(x + y);  

        上述声明中,当执行到x + y时,将抛出OverflowException异常。 checked用来检查运算溢出并引发相应的异常。 当发生OverflowException异常时,z被赋值为0。

        当我们不需要抛出异常时,我们可以使用关键字unchecked。

    1 int x = int.MaxValue;
    2 int y = int.MaxValue;
    3 int z = unchecked(x + y);

        通过执行上面的代码,z的值将被赋值为-2。

    8、Volatile 

    volatile关键字用于定义一个变量,这个变量跨多个线程修改而不被lock(虽然我们大部分的时间锁定它们)。 volatile变量不受编译器优化,因此我们将获得该变量的所有的时间最新的值。见下面的例子:

     1 public volatile int i;
     2 Thread th = new Thread(new ThreadStart(VolatileInvoke));
     3 th.Start();
     4 Thread.Sleep(5000); //Holds current Thread for 5 seconds.
     5 MessageBox.Show("Value of i : " + i);
     6 th.Abort();
     7 
     8 private void VolatileInvoke()
     9 {
    10    while (true)
    11    {
    12          i++;
    13    }
    14 

    线程启动,volatile整数的值增加1,直到它被主线程中止。

    注意:Volatile类型没有线程优化。

    9、StackAlloc  

        在unsafe的C#代码中使用,动态从堆栈分配内存。stackalloc用于快速获取内存。当我们使用堆栈,我们可以利用内存快速存取的优势。我们可以这样声明一个数组:

    1 int* array = stackalloc new int[1000]  

    注意:您应该始终牢记,stackalloc内存是非常有限的。它是由每个线程默认为1MB。因此,如果我们需要大量的内存(超过1MB),我们必须回到原来堆内存结构。

    10、 Global :: 

        当想要用本地的命名空间隐藏的全局的命名空间,这个关键字是非常方便的。假设我们有我们的项目中创建了一个名为System的类,C#中是允许这样做的。当我想使用全局的System空间时,我们必须使用global::.。让我们来看看下面的例子:

     1 internal class System
     2 {
     3         internal class Array :IEnumerable 
     4         {
     5             public int Length
     6             {
     7                 get{return 1000}
     8             }
     9             #region IEnumerable Members
    10             public IEnumerator GetEnumerator()
    11             {
    12                 Debug.Write("This is Dummy Array");
    13                 return base.GetEnumerator();
    14             }
    15 
    16             #endregion
    17         }
    18 }

        现在,如果你要调用System.Array它会调用一个本地定义。要调用全局的System,我们需要使用global::System。当你确定调用全局命名空间时,最好它始终使用global:: 。

    11、Namespace/Class别名

    我们使用using 来定义别名。有2种形式的别名:

    a、Namespace别名:

    当你想缩短比较长的命名空间时,可以使用命名空间的别名。

    1 using Abhishek = System.Drawing;
    2 public class X 
    3 {
    4      public X()
    5      {
    6         Abhishek.Graphics g = this.CreateGraphics();
    7      }
    8 }  

    在这里,我们为System.Drawing的定义了一个别名Abhishek 。因此,我们在代码中引用Abhishek,与引用System.Drawing是相同的。

    b、Class别名:
    您也可以使用using语句来定义一个类引用。例如我写:using Abhishek=System.Drawing.Bitmap;

    Abhisek等同于Bitmap类。我们可以创建Abhishe的对象,直接访问静态函数。

    1 using Abhishek=System.Drawing.Graphics;
    2 public class X
    3 {
    4      public X()
    5      {
    6             Abhishek g = this.CreateGraphics();
    7      }
    8 }

    因此,Abhishek将对应本机的Graphics对象而不是整个命名空间的。

    12、extern别名 

    我们使用C#工作,大多数时候需要引用外部控件集。

    我们会遇到这样的情况,在相同的应用程序中相同命名空间中添加两个版本的dll时。在这种情况下,我们需要外部别名功能,来指定两个不同的程序集。

    例如:

    假设我们添加一个程序集x10.dll(V1),其中有一Y类

    我们添加x20.dll(V2),我们可能要使用Y类

    首先,要参考完全合格的程序集,我们需要在命令行中声明一个别名。

    /r:XV1=X10.dll

    /r:XV2=X20.dll 

    现在参考我们的使用

    1 extern alias XV1;
    2 extern alias XV2;

    13、??

    ??与null值一起使用。在2.0中引入。看以下内容:

    1 MyClass x = null;
    2 = x ?? new MyClass();

    ??的意思是说,如果X是null 值,将new MyClass() ,否则将赋值现有的X值

    14、@variables

        通常是C#不允许使用关键字做变量的。但是有一种方式例外。我们可以通过使用@创建与关键字具有相同的名称的变量。

    假设我们定义:这意味着声明了一个名字为int的变量和并分配10给它。

    1 int @int = 10;

    15、Readonly

        目前,readonly是C#关键字,用来创建不能被程序修改的变量。该声明为readonly的变量,变量的值将被分配一次,它将在整个对象执行过程中保持相同的值。

    声明一个只读变量:

    1 public readonly int readonlyvariable = 20

    声明了一个值为20 的变量。再对这个变量赋值是不允许的。

    16 、Const & readonly 的区别?

        readonly类似关键字const。唯一不同的是, const 变量在编译时定义的,readonly变量在运行时定义。您可以从内部构造函数中分配readonly变量的值,因此根据你的构造函数分配,readonly值可能不同。

    1 public readonly int readsecond;
    2 public Documented()
    3 {
    4       readsecond = DateTime.Now.Second;
    5 

    在这里,readsecond将根据对象的初始化指派不同的值,对于const这是不可能的。

    17 、Default

        对于一般对象,关键字default非常方便。当对象未初始化,它返回的默认值。例如,如果没有赋予任何值,我们都知道整数被初始化为0。当没有赋任何值,字符串为空字符。当不指定任何值,对象为null。

    这些值是根据default关键字分配。
    因此,如果我们写:

    1 int x = default(int);//will be assigned to 0

    类似于:
    int x;
    一般情况下,当类型不确定时,我们可以使用default来分配特定的值给对象。让我们看看该示例:

    1 public T GetDefault<T>()
    2 {
    3      return default(T);
    4 

    该函数返回每个类型的默认值。从而

    因此,我们可以使用关键字default非常容易获取对象默认的分配的值。

    1 int defx = this.GetDefault<int>(); //will assign 0
    2 char defy = this.GetDefault<char>(); // will assign null('\0')
    3 object defz = this.GetDefault<object>(); // will assign null

    18、Nullable Types 

       C#的Nullable类型可以处理空值甚至是基本数据类型。每个nullable类型是来自System.Nullable。我们可以这样定义nullables:

    1 int? nullableint = null

    这里nullableint将被赋值null。

    如果您访问nullable变量,您将获得2个属性。

    HasValue属性将返回false,如果null被分配给变量;

    Value属性返回变量的实际值。

    您还可以使用每种nullable类型的对象的GetValueOrDefault函数来得到变量的默认值。

    结论:

    我的目的是给你一个简短方式介绍一下这些关键字的知识,以及如何去使用它们。请随意发表您的评论。

    代码点击下载

  • 相关阅读:
    DNNClassifier 深度神经网络 分类器
    浏览器对MP4视频 帧宽度 高度的兼容性
    UnicodeEncodeError:'latin-1' codec can't encode character
    文件夹下 文件计数
    the largest value you actually can transmit between the client and server is determined by the amount of available memory and the size of the communications buffers.
    the “identity” of an object
    广告特征 用户特征
    如果一个维度全覆盖,则有效维度应该对该维度全覆盖
    a high-level neural networks AP
    使用 LDA 挖掘的用户喜好主题
  • 原文地址:https://www.cnblogs.com/flish/p/1758666.html
Copyright © 2011-2022 走看看