美文网首页
C#图解教程笔记20170718

C#图解教程笔记20170718

作者: 李大_C | 来源:发表于2017-07-18 17:36 被阅读73次

    <b>访问修饰符</b>
    字段
    访问修饰符 类型 标识符;

    方法
    访问修饰符 返回类型 方法名()
    {
    、、、
    }

    <b>五种成员访问控制如下</b>
    私有的(private) 私有成员只能从声明它的类的内部访问,其他的类不能看见或访问它们。
    公有的(public)
    受保护的(protected)
    内部的(internal)
    受保护内部的(protected internal)

    <b>实例成员</b>:类的每个实例都是不同的实体,它们有自己的一组数据成员,不同于同一类的其他实例,因为这些数据成员都和类的实例相关,所以被称为实例成员。
    <b>静态成员</b>:实例成员是默认类型,但也可以声明与类而不是实例相关的成员,它们被称为静态成员。

    <b>方法</b>
    本质上,方法是一块具有名称的代码,可以使用方法的名称执行代码,也可以把数据传入方法并接收数据输出。
    方法是类的函数成员,方法有两个主要部分,方法头和方法体
    方法头指定方法的特征,包括:
    方法是否返回数据,如果返回返回什么类型;
    方法的名称;
    什么类型的输入可以传入方法。

    方法体包含了可执行代码的语句序列。执行从方法体的第一条语句开始,一直到方法结束.

    <b>常量</b>
    两个特征:声明中必须初始化;声明后不能改变。
    常量声明的语法与变量或字段的声明相同,除了下面内容:
    在类型之前增加关键字const,关键字const不是一个修饰符,而是核心声明的一部分,它必须直接放在类型的前面。;
    必须有初始化语句。

    <b>引用参数</b>
    使用引用参数是,必须在方法的声明和调用中都使用ref修饰符;
    实参必须是变量,在用作实参前必须被赋值。如果是引用类型变量,可以付志伟一个引用或NULL值。

    void MyMethod(ref int val)  //方法声明
    {...}
    
    int y=1;                               //实参变量
    MyMethod(ref y);                //方法调用
    MyMethod(ref 2+3)           //出错,val必须使用变量
    

    <b>输出参数</b>
    输出参数用于从方法体内把数据传出到调用代码,它们非常类似引用参数。它有如下要求:
    <li>必须在声明的调用中都使用修饰符,输出参数的修饰符是out而不是ref</li>
    <li>实参必须是变量,不能是其他表达式类型。</li>

    <b>参数数组</b>
    重点:
    <li>在一个参数列表中只能有一个参数数组。</li>
    <li>如果有,他必须是列表中的最后一个</li>
    声明一个参数数组必须要做的事:
    <li>在数据类型前使用params修饰符</li>
    <li>在数据类型后放置一组空的方括号</li>

    void ListInts(params int[] inVals)
    {....}
    

    <li>数组是一组整齐的相同类型的数据项。</li>
    <li>数组使用一个数字索引进行访问。</li>
    <li>数组是一个引用类型,因此它的所有数据项都保存在堆中</li>

    ListInts(10,20,30):              //所有元素必须是方法声明中指定的类型
    
    int[] intArray={1,2,3};
    ListInts(intArray);               //一个数组变量
    

    <li>在声明中需要修饰符</li>
    <li>在调用中不允许有修饰符</li>

    参数类型 修饰符 是否在声明时使用 是否在调用时使用 执行
    系统把实参的值复制到形参
    引用 ref 形参是实参的别名
    输出 out 形参是实参的别名
    数组 params 允许传递可变数目的实参到方法

    <b>栈帧</b>
    当一个方法被调用时,在栈顶分配了一块内存用于保存一定数量与方法相关的数据项,这块内存叫方法的栈帧。

    <ul><li>栈帧含有保存下列内容的内存:</li>
    <ol><li>返回地址——就是方法退出时在哪儿继续执行</li>
    <li>分配内存的参数——就是方法的值参数,如果有参数数组</li>
    <li>与方法调用相关的其他各种管理数据项</li></ol>
    <li>方法被调用时,它的整个栈帧被压入栈中。</li>
    <li>方法退出时,它的整个栈帧被从栈中弹出。弹出一个栈帧有事也称为释放栈</li>

        class Program
        {
            static void MethodA(int par1,int par2)
            {
                Console.WriteLine("Enter MethodA:{0},{1}",par1,par2);
                MethodB(11, 18);
                Console.WriteLine("Exit MethodA");
            }
            static void MethodB(int par1, int par2)
            {
                Console.WriteLine("Enter MethodB:{0},{1}", par1, par2);
                Console.WriteLine("Exit MethodB");
            }
    
            static void Main(string[] args)
            {
                Console.WriteLine("Enter Main");
                MethodA(15, 30);
                Console.WriteLine("Exit Main");
                Console.ReadKey();
            }
        }
    

    输出结果为:


    Enter Main
    Enter MethodA:15,30
    Enter MethodB:11,18
    Exit MethodB
    Exit MethodA
    Exit Main


    栈帧.png

    方法重载

    一个类中可以有一个以上的方法拥有相同的名称,这叫做方法重载,使用相同名称的每个方法必须有一个和其他方法不相同的签名

    • 方法的签名有下列信息组成,它们在方法声明的方法头中:
    • 方法的名称;
    • 参数的数目;
    • 参数的数据类型和顺序;
    • 参数修饰符;
    • 返回类型不是签名的一部分,而认为它是签名的一部分是一种常见的错误。
    • 形参的名称也不是签名的一部分。
      例:
    class A
    {
    long Add(int a,int b)        {return a+b;}
    long Add(int a,int b,int c)  {return a+b+c;}
    long Add(float a,float b)    {return a+b;}
    long Add(long a,long b)      {return a+b;}
    }
    


    类进阶

    实例类成员
    改变一个实例的字段拷贝的值不影响其他实例的拷贝的值

    class D
    {
       public in num1;
    }
    class Program
    {
       static void Main()
      {
       D d1=new D();
       D d2=new D();
       d1.num1=10;d2.num1=25;
       Console.WriteLine("d1={0},d2={1}",d1.num1,d2.num1)
      }
    }
    

    输出结果


    d1=10,d2=25


    静态字段被类的所有实例共享,所有实例都访问同意内存位置,所以,如果该内存位置的值被一个实例改变了,这种改变对所有的实例都可见。

    class D
        {
            int num1;
            static int num2;
            public void SetVars(int v1, int v2)//设置值
            { num1 = v1; num2 = v2; }
            public void DisPlay(string str)    //显示值
            { Console.WriteLine("{0}:num1={1},num2={2}",str,num1,num2); }
        }
        class Program
        {
            static void Main()
            {
                D d1 = new D();
                D d2 = new D();//创建两个实例
    
                d1.SetVars(2, 4);//设置d1的值
                d1.DisPlay("d1");
    
                d2.SetVars(22,14);//设置d2的值
                d2.DisPlay("d2");
    
                d1.DisPlay("d1");//再次显示d1
    
                Console.ReadKey();
            }
        }
    

    输出结果为:


    d1:num1=2,num2=4
    d2:num1=22,num2=14
    d1:num1=2,num2=14


    实例成员在实例被创建时开始存在,当实例被销毁时停止存在。然而,静态成员及时没有类的实例也存在并可以访问。
    例:

    class D
        {
            int num1;
            static public int num2;
            
        }
        class Program
        {
            static void Main()
            {
                D.num2 = 4;//没有实例化
                Console.WriteLine("num2={0}",D.num2);
                Console.ReadKey();
            }
        }
    

    输出结果


    num2=4


    静态函数成员

    • 同静态字段一样,静态函数成员独立于任何类实例。即使没有类的实例,仍可以调用静态方法。
    • 静态函数成员不能访问实例成员。然而,它们能访问其它静态成员。

    成员常量

    • 声明在类声明中;
    • 不能再常量成员声明以后给他赋值;
    • 成员常量对类的每个实例都是可见的,及时没有类的实例它们也可以使用;
    • 常量在内存中没有自己的储存位置,而是在编译时被编译器替换。(ps:我一直以为是和值类型一样放在栈中呢( ̄▽ ̄)/);

    属性
    就像字段,属性有如下特征:

    • 它是命名的类成员;
    • 它有类型;
    • 他可以被赋值和读取;
      然而和字段不同的是,属性是一个函数成员。
    • 他不为数据储存分配内存;
    • 它执行代码;
      属性是指定的一组两个匹配的,称为访问器的方法
    • set访问器用于为属性赋值;
    • get访问器用于从属性取值。
    image.png

    属性本身没有任何储存,访问器决定如何处理发进来的数据,以及什么数据应该被发送出去,属性使用一个字段做储存
    set访问器接受他的输入参数value,并把他的值赋值给字段
    get访问器只是返回字段的值


    image.png

    使用属性
    写入和读取属性的方法与访问字段一样,访问器被隐式调用

    int MyvAalue       //属性声明
    {
      set{...}
      get{...}
    }
    ...
    MyvAalue=5;    //赋值隐式调用set方法
    z=MyvAalue;    //表达式:隐式调用get方法
    
    

    属性和关联字段

    image.png

    只有get访问器的属性称为只读属性。
    只有set访问器的属性称为只写属性。
    两个访问器至少要有一个必须定义,否则编译器会产生一条错误信息。

    静态属性和
    属性也可以声明为static,静态属性的访问器和所有静态成员一样:

    • 不能访问类的实例成员——虽然它们能被实例成员访问。
    • 存在,不管类是否有实例;
    • 当从类的外部访问时,必须使用类名引用,而不是实例名。


      image.png

    实例构造函数
    实例构造函数是一个特殊的方法,他在类的每个新实例创建的时候执行。

    • 构造函数用于初始化类实例的状态;
    • 如果希望能从类的外部创建类的实例,需要声明构造函数为public;
    • 构造函数的名称和类名相同。
    • 构造函数不能有返回值。


      image.png

    静态构造函数
    构造函数也可以声明为static,通常静态构造函数初始化类的静态字段
    静态构造函数在下列方面和实例构造函数不同:

    • 静态构造函数声明中使用static关键字。
    • 类智能有一个静态构造函数,而且不能带有参数。
    • 静态构造函数不能有访问修饰符。
    class Class1()
        { 
                   static Class1()
                  {
                       ...                            //静态构造函数的函数体
                   }
         ...
         }
    

    类既可以有静态构造函数也可以有实例构造函数。

    静态构造函数示例:

    class RandomNumber
        {
            private static Random RandomKey;//私有静态字段
            static RandomNumber()//静态构造函数
            {
                RandomKey = new Random();//初始化
    
            }
            public int GetRandomNumber()
            {
                return RandomKey.Next();
            }
        }
        class Program
        {
            static void Main()
            {
                
                    RandomNumber a = new RandomNumber();
                    RandomNumber b = new RandomNumber();
                    Console.WriteLine(a.GetRandomNumber());
                    Console.WriteLine(b.GetRandomNumber());
                
                
                Console.ReadKey();
            }
        }
    

    输出结果为:
    728118870
    1501976979


    析构函数

    • 每个类只能有一个西沟函数;
    • 析构函数不能带参数;
    • 析构函数不能带访问修饰符;
    • 析构函数和类有相同的名称,但以一个“~”字符做前缀;
    • 析构函数只能对类的实例起作用,因此没有静态析构函数;
    • 不能在代码中显示的调用析构函数,相反,他在垃圾收集过程中调用,当成垃圾收集器分型代码,并确定在代码中没有任何途径引用该对象。
      例:
    Class1
    {
       ~Class1()
      {
           cleanuoCode;
      }
    ...
    }
    
    • 如果不需要就不要执行析构函数,它们会带来性能上的开销。
    • 西沟函数直营释放对象自己的外部资源,他不应该访问其它的对象,应为无法假定这些对象还有没有被收集。

    析构函数本质上是Dispose代码的子集。

    redonly修饰符
    字段可以用redonly修饰符声明,其作用类似于声明一个字段为const,一但值被设定就不能改变

    this关键字
    this关键字在类中使用,是对当前实例的引用。它只能被用在下列类成员的代码块中:

    • 实例构造函数;
    • 实例方法;
    • 属性和索引的实例访问器
      this被用于下列目的:
    • 用于区分类的成员和本地变量,或参数。
    • 作为调用方法的实参。

    索引

    image.png

    索引是一组get和set访问器,类似于属性的访问器。

    string this [int index]
    {
      set{SetAccessorCode}
      get{GetAccessorCode}
    }
    

    相关文章

      网友评论

          本文标题:C#图解教程笔记20170718

          本文链接:https://www.haomeiwen.com/subject/hnvckxtx.html