C#语法复习2
第五章 方法
1、方法是一块具有名称的代码
包括:方法体、方法头
局部变量必须被赋值才可以执行下面的操作。实例变量有隐式初始化。有时候,类型推断可以用var关键字,类似于C++当中的auto。用于局部变量。
C#中,不能在第一个名称的有效范围内去声明另一个同名的本地变量。
2、本地常量:局部常量。Const 关键字。Const double PI = 3.1415926; 在编译期决定其值。
3、 参数:形参与实参。参数也有几种:值参数/引用参数。
值类型与值参数是两种不同的概念:值类型就是类型本身包含其值。而值参数是把实参的值复制给形参。
Void mymethod(myclass f1, int f2)
{
F1.val += 5;
F2+= 5;
}
调用: mymethod(a1,a2);
执行过程:
方法开始时,系统在栈中为形参分配空间,并从实参复制值。a1为引用类型,所以引用被复制,但指向相同。
在使用引用参数时,必须加关键字 ref。 void method(ref int val){ xxxx }, 方法调用 method(ref y);//必须使用变量。
举例:
Void mymethod(ref myclass f1,ref int f2)
{
F1.val += 5;
F2+= 5;
}
调用: mymethod(ref a1,ref a2);
执行过程:不会开辟新的内存单元,只是把形参名设置为实参的别名而已。a1与f1,引用相同的位置。
引用类型作为值参数和引用参数:
我们修改引用参数的成员时,无论是作为值参数还是引用参数,效果都一样。但,当我们去修改引用类型本身时,那么其作为值参数与引用参数是不同的。
请看下面的图形:
4、输出参数
需要加关键字 out
Void mythod(out int val); //形参也是实参的别名,且我们通过方法体之后就会知道你传入的实参的值。方法体内部会对实参赋值。
5、参数数组
前面是一个实参对应一个形参,现在是多个实参对应一个特殊的形参。
关键字:params 比如 void mythod(params int[] vals){ }
调用: int[] arrays = {1, 2 ,3}; mythod(arrays);
调用时,如果是用值类型传递,即实参是值,数组参数是值类型,实参不受影响。
如果是引用类型传递,即实参是数组名,数组参数是引用类型,实参受方法内部影响。
6、方法重载
方法名称相同,方法特征不同即可。
7、命名参数
给参数命名,这样我们可以以任意顺序调用。
Void mythod(int a, int b, int c);
参数的名字和值: 调用时指定名称和值即可。 Mythod(c:2, a:4, b: 1);
8、可选参数
就是我们在调用时,可以调用这个参数,也可以省略这个参数。这时,必须在声明的时候给参数提供默认值。
Void mythod(int a, int b, int c = 2);
先是必填参数+ 可选参数+ params 参数。
9、栈帧:就是一个个方法进栈。
-
//1、类型推断与var关键字(用于局部变量)
-
//2、申明局部常量 const double PI = 3.1415926;
-
//3、基本结构 顺序 选择 循环
-
//4、方法调用
-
//5、返回值 return x;
-
//6、返回语句和void方法 return;用于void声明的方法
-
//7、参数:返回多个值与传入多个值的特殊变量
-
// 实参:初始化形参的表达式或者变量
-
//8、值传递与引用传递
-
-
MyClass a1 = new MyClass();
-
int a2 = 10;
-
Mythod(a1, a2);
-
Mythod1(ref a1, ref a2);
-
//9、引用传递必须在方法的申明与调用中都使用ref修饰符
-
//实参必须为变量,如果是引用类型变量,可以赋值为一个引用或者null。不会为形参分配内存
-
//10、输出参数,与引用传递用法基本一致
-
int a3;
-
Mythod2(out a1, out a3);
-
//11、参数数组
-
//声明时需要加修饰符params,调用时不需要。
-
// 1) 用数组参数初始化堆当中数组
-
int first = 1, second = 2, third = 3;
-
MyClass mc = new MyClass();
-
mc.ListInts(first, second, third);//调用方法
-
// 2) 用数组作为实参
-
int[] myarr = new int[] { 4, 5, 6 };
-
mc.ListInts(myarr);
-
//12、方法重载:方法名称相同,特征不同。返回值无法区分。
-
//13、命名参数:在方法调用的时候,我们可以指定参数名称,这样可以改变实参传入方法的顺序
-
int result = mc.Cal(c: 2, a: 4, b: 3);
-
Console.WriteLine("result: {0}", result);
-
//14、可选参数 只能是值参数类型。
-
//为表名某个参数是可选的,必须在方法声明的时候为参数提供默认值。
-
//数据类型:值类型 引用类型。
-
//参数类型:值,ref,out,params。
-
mc.Cal1(5, 6);//可以搭配命名参数
-
mc.Cal1(2,b: 2, c: 8);//命名参数必须放在最后写
-
//15、栈帧 栈的调用 递归
第六章 深入理解类
数据成员有:字段、类型、常量
函数成员有:方法、属性、构造函数、运算符、索引器、事件。
属性:主要是对字段的封装,我们可以有选择性的定义某个实例变量。
Int Value
{
Set {Value = value > 100 ? 100 : value; }
Get{return Value;}
}
当然,我们也可以通过设置 set和get访问器来设置 只读和只写属性。
索引器是一组set和get访问器。
-
//1、成员修饰符 规定:如果有修饰符,必须放在核心声明之前。如果有多个修饰符,顺序可变。
-
//2、静态实例变量 类的静态成员与实例成员分开保存
-
// 静态实例变量可以在方法中初始化,而C++中的实例变量在 类外面初始化。而常量成员必须在类中初始化,方法中没有常量成员。
-
class D
-
{
-
int mem1;
-
static int mem2;
-
public void SetVars(int v1, int v2)
-
{
-
mem1 = v1;
-
mem2 = v2;
-
}
-
public void Display(string str)
-
{
-
Console.WriteLine("{0}:mem1={1},mem2={2}", str, mem1, mem2);
-
}
-
-
}
-
-
-
//调用
-
D d11 = new D();
-
D d22 = new D();
-
d11.SetVars(2, 4);
-
d11.Display("d11");
-
d22.SetVars(15, 17); //静态变量已改变,且为共有变量,可以脱离实例化而存在
-
d22.Display("d22");
-
d11.Display("d11");
-
class X
-
{
-
static public int A;
-
public const int val = 100;//类似于define 必须定义在类型内且初始化。没有 static const int val = 10;语句。
-
static public void PrintValA()//静态函数成员可以访问静态成员变量,但不能访问实例变量
-
{
-
Console.WriteLine("A : {0}",A);
-
}
-
-
private int Value;//字段:分配内存
-
public int MyValue//属性:未分配内存 (属性会根据是写入还是读取来隐式的调用适当的访问器)
-
{
-
set
-
{
-
Value = value;//属性使用实例变量来存储数据。
-
}
-
get
-
{
-
return Value;
-
}
-
}
-
-
public int myval //自动实现属性
-
{
-
set;
-
get;
-
}
-
public static int val111 { set; get; }//静态属性
-
}
-
}
-
-
//调用
-
X.A = 10;//静态成员可以在使用的时候,在赋值
-
X.PrintValA();
-
//成员常量
-
Console.WriteLine("{0}", X.val);//必须加public这边才能找到它
-
//3、属性vs访问器 set与get访问器
-
// 一般属性被用来封装字段,然后调用时,用属性即可。
-
class A
-
{
-
public int X = 1;
-
public int Y = 2;//设置为public的实例变量可以调用对象初始化语句
-
private static Random random;
-
static A()//静态构造函数
-
{
-
random = new Random();//初始化Random
-
}
-
public int GetRandom()
-
{
-
return random.Next();
-
}
-
int val;
-
public A() //一定要加修饰符
-
{
-
val = 10;
-
}
-
public A(int value)
-
{
-
val = value;
-
}
-
}
-
-
//调用
-
//4、构造函数 静态构造函数
-
A a11 = new A();
-
A a22 = new A();
-
Console.WriteLine("{0}", a11.GetRandom());
-
Console.WriteLine("{0}", a22.GetRandom());
-
//5、对象初始化语句
-
//注意:创建对象的代码必须能够访问要初始化的字段与属性。比如,X与Y 字段必须什么为public。
-
A a33 = new A { X = 2, Y = 3 };//对象初始化语句
-
A a44 = new A();
-
Console.WriteLine("a33:x={0},y={1}", a33.X,a33.Y);
-
Console.WriteLine("a44:x={0},y={1}", a44.X, a44.Y);
-
-
//6、析构函数 使用.net是不需要为类编写析构函数。假如是win32 api就需要释放其资源了
-
//7、read only 修饰符/关键字,其用法类似于const,但可以对其实例变量赋值,赋值一般在构造函数中进行。
-
//8、this 关键字,防止实例变量被屏蔽,用于带参的构造函数或者方法中。(它是对当前对象的引用)
-
class Employee //声明索引器 仿照 属性,用来为多个数据成员提供get与set属性。
-
{
-
public string a1;
-
public string a2;
-
public string a3;
-
-
public string this[int index]
-
{
-
set
-
{
-
switch (index)
-
{
-
case 0: a1 = value;break;//这个value是默认的形参
-
case 1: a2 = value;break;
-
case 2: a3 = value;break;
-
default: throw new ArgumentOutOfRangeException("index");
-
}
-
}
-
get
-
{
-
switch (index)
-
{
-
case 0: return a1;
-
case 1: return a2;
-
case 2: return a3;
-
default: throw new ArgumentOutOfRangeException("index");
-
}
-
}
-
}
-
}
-
-
//调用
-
//9、索引器,用来为多个实例变量提供set与get属性。支持重载,只要参数列表不同就可以。
-
-
Employee ee = new Employee();
-
ee[0] = "zhu";
-
ee[1] = "xue";//索引器set访问器的自动调用
-
ee[2] = "kui";
-
Console.WriteLine("ee:{0},{1},{2}", ee[0], ee[1], ee[2]);
-
class Person
-
{
-
public string Name { get; private set; }//属性的访问级别默认为public
-
private int a;
-
public Person(string name) //一般实例变量默认修饰符为private,所以要想其他类能够找到,必须申明为public,不然只能在类内部自己混。
-
{
-
Name = name;
-
}
-
}
-
-
//调用
-
//10、访问器的访问修饰符
-
//注意:访问器的访问修饰符比成员的访问级别有更高的限制性
-
//访问器的默认修饰符为public。
-
Person peron = new Person("zhuxuekui");
-
//peron.a = 5; //错误,a为private属性,访问不到。
-
Console.WriteLine("{0}", peron.Name);
-
//11、分步类、分步类型和分步方法
-
//类似于.h 和 .cpp 文件。就是说,一个类或者方法可以拆成几部分分别定义。 类前面加 partial 类型修饰符。