美文网首页
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

    访问修饰符 字段访问修饰符 类型 标识符; 方法访问修饰符 返回类型 方法名(){、、、} 五种成员...

  • C#图解教程笔记20170721

    接口声明可以有任何的访问修饰符public,internal,protected和private。接口的成员是隐式...

  • C#图解教程笔记20170720

    全局程序集缓存(GAC),放进GAC的程序集称为共享程序集 只有强命名程序集能被添加到GAC GAC不仅值接受.d...

  • C#图解教程笔记20170719

    分部类和分部类型每个局部声明必须被表位partial class ,而不是单独的关键字class。 类和继承 类继...

  • C#图解教程笔记20170717

    2017/7/17 C#和.NET框架 .NET框架,CLR的C#语言 .net框架是一个独立发布的软件包,包括了...

  • C#类型

    《C#图解教程》学习记录 C#程序是一组类型声明。类型是一种用来创建数据结构的模板。 预定义类型 C#提供了16种...

  • C# 中的栈和堆

    本文是《C# 图解教程》的笔记。 程序运行时,它的数据必须存储在内存中。一个数据项需要多大的内存、存储在什么地方、...

  • 18072206脚本基础1

    0722视频:6-1 6-2 脚本基础 课前 用刻意练习来学习编程语言《c#图解教程》pfd《Head.First...

  • 2018上半年阅读计划

    毕设需要 《3ds Max从入门到精通》、《C#图解教程》、《Unity3D游戏开发》、《Unity游戏设计与实现...

  • C#入门教程(二)–C#常用快捷键、变量、类型转换-打造C#

    C#入门教程(一)–.Net平台技术介绍、C#语言及开发工具介绍-打造C#学习教程 上次教程主要介绍了.Net平台...

网友评论

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

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