【备忘】C#语言基础-1
C#基础
注意区别哟!
- C#是一种托管语言,与C++不同,不能直接操作系统底层,依赖于 framework。
- 如果局部变量和全局变量同名,全局变量就会被屏蔽。
- 函数的返回值类型不是签名的一部分,所以不能定义两个仅返回类型不同的函数,它们实际上有相同的签名。
Debug.WriteLine()
命令不能编译为可发布的程序,在发布版本中,该命令会消失。- 接口可以继承自其他接口,与类不同的是,接口可以继承多个基接口。
- C#的类定义中,只能有一个基类。
- 默认情况下,类声明为内部的,即只有当前项目中的代码才能访问他,可使用
internal
访问修饰符关键字来显示的指定这一点,另外还可以指明为公共类(public
),其他项目中的代码可以访问。 typeof
是C#运算符,可以把类名转换为System.Type
对象。ICloneable
实现接口及方法Clone()
,可实现深复制。- 结构类型是值类型,而类是引用类型。
sealed
密封类关键字,不可被继承。- 命名方式大部分是PascalCasing方式,私有字段是camelCasing方式。
base
关键字调用重写或隐藏的基类方法。this
引用的是当前对象实例。partial
关键字,定义部分类。
函数引用传递
函数声明和调用时都必须使用ref
关键字。
函数输出参数
与引用相同,声明和调用时都必须使用out
关键字。但还是有以下区别:
- 把未赋值的变量用作ref 参数是非法的,但可以把未赋值的变量用作out 参数。
- 另外,在函数使用out 参数时,out 参数必须看作是还未赋值。
即调用代码可以把已赋值的变量用作out 参数,存储在该变量中的值会在函数执行时丢失。
委托
委托(delegate)是一种可以把引用存储为函数的类型。委托的声明非常类似于函数,但不带函数体,且要使用 delegate 关键字。委托的声明指定了一个返回类型和一个参数列表。
在定义了委托后,就可以声明该委托类型的变量。接着把这个变量化初始为与委托有相同返回类型和参数列表的函数引用。之后,就可以使用委托变量调用这个函数,就像该变量是一个函数一样。
有了引用函数的变量后,还可以执行不能用其他方式完成的操作。例如,可以把委托变量作为参数传递给一个函数,这样,该函数就可以使用委托调用它引用的任何函数,而且在运行之前无需知道调用的是哪个函数。
类与对象
比如,类是指汽车的模板,活着用户创建汽车的规划;而汽车本身是这些规划的实例,看作是对象。
事件
对象可以激活和使用事件,作为它们处理的一部分。使用事件可以创建事件所驱动的应用程序,比比皆是。
引用类型和值类型
在C#中,数据根据变量的类型以两种方式中的一种存储在一个变量中:
- 值类型在内存的同一个地方存储它们自己和他们的内容。
- 引用类型存储指向内存中其他某个位置(称为堆)的引用,实际内容存储在这个位置。
区别:值类型总是包含一个值,而引用类型可以是null,表示它们不包含值。但是可以使用可空类型创建一个值类型,使值类型在这个方面的行为方式类似于引用类型(即可以为null)。
结构与类:结构类型是值类型,而类是引用类型。
System.Object
类
所有的类都继承自System.Object
,所以这些类都可以访问该类中受保护的成员和公共成员。
图标含义
定义
成员访问级别
- public——任何代码访问。
- private——类中的代码访问(如果没有使用任何关键字,就默认使用这个关键字)。
- internal——成员由定义他的程序集(项目)内部的代码访问。
- protected——类或派生类中的代码访问。
定义字段
- .NET Framework中的公共字段以PascalCasing形式命名,私有字段通常使用camelCasing来命名。
readonly
关键字表示这个字段只能在执行构造函数的过程中复制,或由初始化赋值语句复制。
定义方法
- virtual——方法可以被重写。
- abstract——方法必须在非抽象的派生类中重写(只用于抽象类中)。
- override——方法重写了一个基类方法(如果方法被重写,就必须使用该关键字)。
- extern——方法定义放在其他地方。
如果使用了
override
,也可以使用sealed
来指定在派生类中不能对这个方法做进一步的修改。
集合、比较、转换
System.Collections
名称空间中的几个接口提供了基本的集合功能:
集合
ArrayList
集合不需要初始化大小,与数组不同。
foreach
语句。Count
属性。Remove()
和RemoveAt()
删除项。AddRange()
和InsertRange()
方法一次添加好几项。IndexOf()
查看索引值。
CollectionBase
类,提供了一些集合基本功能。派生类可以使用freach
语句。
public class Animals : CollectionBase
{
//必要代码
}
DictionaryBase
键控集合,与上个集合基本相同,区别是:没有索引,使用KEY值。
比较
对象之间的两类比较:
- 类型比较
- 值比较
类型比较
GetType()方法,所有的类都从 System.Object 中继承了这个方法,这个方法和 typeof()运算符一起使用,就可以确定对象的类型。
is 运算符并不是说明对象是某种类型的一种方式,而是可以检查对象是否是给定类型,或者是否可以转换为给定类型,如果是,这个运算符就返回true。
值比较
使用 IComparable
和 IComparer
接口,它们可以用标准的方式定义比较对象的过程。 这是由.NET Framework 中各种集合类提供的方式, 是对集合中的对象进行排序的一种绝佳方式。
- 运算符重载
public static AddClass1 operator +(AddClass1 op1, AddClass1 op2)
{
AddClass1 returnVal = new AddClass1();
returnVal.val = op1.val + op2.val;
return returnVal;
}
可以重载下述运算符:
- 一元运算符:+, -, !, ~, ++, --, true, false
- 二元运算符:+, -, *, /, %, &, |, ˆ , <<, >>
- 比较运算符:==, !=, <, >, <=, >=
不能重载赋值运算符,例如+=,但这些运算符使用与它们对应的简单运算符,例如+,所以不必担心它们。重载+表示+=像预期的那样执行。=运算符不能重载,因为它有一个基本的用途。但这个运算符与用户定义的转换运算符相关。
也不能重载&&和 ||, 但它们可以在计算中使用对应的运算符&和 |, 所以重载&和 | 就足够了。
一些运算符如 < 和 > 必须成对重载。这就是说,不能重载 <,除非也重载了 >。在许多情况
下,可以在这些运算符中调用其他运算符,以减少需要的代码数量(和可能发生的错误)。
也可以重写 Object.Equals()
和 Object.GetHashCode()
方法来比较。
- IComparable和IComparer接口
IComparable 和 IComparer 接口是.NET Framework 中比较对象的标准方式。这两个接口之间的
差别如下:
- IComparable 在要比较的对象的类中实现,可以比较该对象和另一个对象。
- IComparer 在一个单独的类中实现,可以比较任意两个对象。
IComparable 提供了一个方法CompareTo(),这个方法接受一个对象。例如,实现可以为实现方
法传送一个Person 对象,以便确定这个人是否比当前的人更年老还是更年轻。实际上,这个方法返
回一个int,所以也可以确定第二个人与当前的人的年龄差。
- 使用IComparable和IComparer接口对集合排序
许多集合类可以用对象的默认比较方式进行排序,或者用定制方法来排序。ArrayList 就是一个
示例,它包含方法 Sort(),这个方法使用时可以不带参数,此时使用默认的比较方式,也可以给它
传送IComparer 接口,以比较对象对。
在给ArrayList 填充了简单类型时,例如整数或字符串,就会进行默认的比较。对于自己的类,
必须在类定义中实现IComparable,或者创建一个支持IComparable 的类,来进行比较。
转换
as 运算符,它一般适用于引用类型的转换。
as 运算符使用下面的语法,把一种类型转换为指定的引用类型:
<operand> as <type>
这只适用于下列情况:
- operand 的类型是 type 类型
- operand 可以隐式转换为 type 类型
- operand 可以封箱到 type 类型中
如果不能从 operand 转换为 type ,则表达式的结果就是null。