C#基本概念

1:C#基本概念
类:抽象的概念,将相同性质的对象抽象成一个类,封装起来
对象:具体的事物,是类的实例
命名空间定义了一个声明区域
接口:和类很像,用来描述某一类对象具有某种属性和行为以及事件,但是不具体指明这些属性和行为以及事件到底是什么
描述一种规范,但是不具体实现这一种规范(由继承接口的类去实现)






2:C#类型
C#强类型语言,所有的操作都会经过编译器的类型检查
值类型(继承System.ValueType):(直接存储的数据)
值类型要么是包括结构类型要么是枚举类型)
值类型不能为null
浮点数运算时会产生3种特殊的值
1:正零和负零(与简单的零相等)
2:正无穷大(无穷大是由非零数字和零除产生的)(1.0/0.0)和负无穷大(-1.0/0.0)
3:非数字值(浮点运算(零和零除)产生的):常缩写为NaN
枚举类型:
在声明枚举时,如果为该枚举添加了位标记Flags,那么该枚举的枚举数可以按照位运算方法进行运算
[Flags]
enum File
{
None=0,
Read=1,
Write=2,
Delete=4
}
引用类型:(存储的是数据的地址)
1:类类型(自定的类型)
2:对象类型(object类型)
3:字符串类型
4:数组类型int[] array
5:接口类型
6:委托类型


装箱和拆箱
装箱:将值类型转换为引用类型
创建一个临时对象实例将变量i复制到这个实例中然后赋值给object类型的对象
int i = 10
object o = i(装箱操作)int型的变量隐式转换为引用类型赋值给object类型的o
4种常见的装箱操作
1:值类型到object类型
2:值类型到system.valuetyp类型
3:值类型到值类型的任何接口类型
4:枚举类型到system.enum类型
拆箱:将引用类型转换为值类型
int i = 10
object o = i
int j = (int)o(拆箱操作)将引用类型o转换为int类型的值并赋给int型的变量j
4种常见的拆箱操作
1:object类型到值类型
2:system.valuetyp类型到值类型
3:值类型的任何接口类型到值类型
4:system.enum类型到枚举类型




第三章变量
3:变量:表示存储的位置(数据存储空间的表现)
声明一个变量,变量可能具有初始值(初始已赋值)也可能没有初始值(初始未赋值)
int a = 12;数据12存储的位置为a
值类型都有默认初始值,例如声明变量int a;a的默认值为0
引用类型没有初始默认值
1:静态变量:
静态变量都有初始默认值,如果静态变量的类型为引用类型它的默认值为null
在程序编译之后就已经存在,它总是在包含了它的那个类型(指的是类)的静态构造函数执行之前就存在了,在关联的应用程序域终止时终止
2:实例变量class A{int a;a为实例变量}
只有在对象实例化才分配给实例变量内存
3:局部变量:
在程序块中声明的变量,
注意:局部变量是没有默认初始值,要使用局部变量必须要赋初始值
4:引用参数(ref int a):
不创建新的存储位置(内存空间),和基础变量操作的是同一个变量
使用引用参数注意三个方面
1:函数在传递ref参数时,ref参数必须明确赋值
2:在函数内部ref参数被视为初始已赋值
5:输出参数(out int i):
不创建新的存储位置,使用的是基础变量的存储位置
输出参数注意三个方面
1:输出参数变量在函数传递之前不一定要明确赋值
2:在函数内部out参数被视为初始未赋值
3:在函数返回前out参数必须明确赋值
6:值参数:
指的是方法的参数,相当于局部变量,初始化来自该方法调用提供的相应参数,
在内存中给其分配了一块新的内存空间
作用域:调用函数时,值参数开始存在,用给定实参的值进行初始化,当函数返回时值参数停止存在


as运算符实现显示转换
e as T
e:必须为表达式
T:必须为引用类型
返回值为T类型,如果转换失败则返回null






第5章:表达式和运算符
表达式
特殊的表达式this,new,base
this:(引用的是当前实例对象)
1:限定名称相同的成员
2:将对象本身作为参数
3:声明索引器
base:在派生类中访问基类的成员
new:创建对象


运算符
位运算符&(与)|(或)^(异或)
逻辑运算符&&, ||, !


转换运算符
类型测试运算符包括is和as
is运算符:动态检查对象的运行时类型是否与给定类型兼容,返回值为bool类型
e is T,e为表达式,T为类型
as运算符:将一个值显示转换为一个给定的引用类型,转换失败返回null








第6章:程序最小的单位(语句)
1:空语句while(true)
2:标记语句
int j = 0
Addj:j++;标记语句goto语句可以跳转到标记语句
for(初始化表达式,条件表达式,迭代表达式)
foreach(类型 迭代变量 in 表达式(集合))当我们无法判断集合的元素的个数时
foreach执行完毕的条件是否为集合的最后一个元素是返回为true跳出foreach循环
break语句只能用于while,do,for,switch,foreach


throw抛出语句
throw expression(可以有expression也可以不要expression(throw;))


表达式语句有下面7种
i =20;赋值表达式 count();调用表达式
object obj = new object()创建对象表达式
前缀自加/自减表达式
后缀自加/自减表达式


using语句用来定义一个范围,并在该范围之外释放一个或者多个对象
即用于获取一个或多个资源,并执行一个语句,然后释放该资源
语法形式:
using (resourse-acquisition) embedded-statment
resourse-acquisition:用于获取一个或者多个资源,该资源必须
继承System.IDisposable的类或结构
embedded-statment:为嵌入语句,当using语句获取资源后,将执行该嵌入语句
执行using语句一般有三个步骤:获取资源,使用资源,释放资源
using (ResourceType source = expression) statement
ResourceType :资源的类型
source = expression:获取资源
statement:使用资源
ResourceType为值类型时using (ResourceType source = expression) statement等效:
{
ResourceType source = expression
try
{
statement
}
finally
{
((IDisposable)resource).Dispose();
}
}
ResourceType为引用类型时using (ResourceType source = expression) statement等效:
{
ResourceType source = expression
try
{
statement
}
finally
{
if(resource!=null)((IDisposable)resource).Dispose();
}
}


lock语句,给对象(内存空间)加锁


checked和unchecked语句:用于控制整形算术运算和转换的溢出检查,用于块不是表达式
如果测试是否产生了溢出使用checked语句
如果希望忽略溢出使用unchecked语句




第7章:命名空间:避免名称冲突(命名空间不能加修饰符默认public)
给命名空间创建一个新的名称(别名)
using oldnamespace = newnamespace
using t = test(命名空间test)








第8章:类(将数据和与之相关的运算打包在一起,统一考虑)
类的访问权限
new,public,private,protected
internal:类只能在当前程序集(当前应用程序)中访问
abstract:指定类为抽象类(不能被实例化)
sealed:指定类为密封类,不能继承,所以不能作为抽象类和基类
new运算符:子类拥有和父类的同名方法(字段,属性),编译器会发出警告为了避免
警告,需要在子类定义该方法的时候,使用new进行修饰
new修饰符用于显示隐藏从基类继承的方法,并用派生类的方法替换基类的方法
2:继承:除了构造函数和析构函数不能被继承
3:类的实例化 Program是一个类
Program p;此时p的值为null
p = new Program ()此时p的值不为null可以被访问和引用
4:类的成员
1:常量,在定义时就要赋值,不能修改
2:字段(类的变量)
字段的修饰:readonly,static,volatile(易失字段)
int i(实例的字段);static readonly i(静态只读字段);static int i;readonly int i;
静态变量在程序中只开辟一块内存空间来存储静态字段,属于类的成员
给只读字段赋值:在声明只读字段的语句中赋值
3:方法
方法的参数(值参数相当于局部变量)有:
参数数组:声明参数时带有params修饰符params int[]
引用参数:
输出参数:
静态方法:类的方法(类创建好就存在了)
实例方法:属于类的实例
虚方法和重写方法
虚方法(关键字virtual)
重写方法(关键字override):在派生类重写virtual修饰的方法
密封方法:
在方法的声明中添加关键字sealed,则该方法在派生类中不能被重写
抽象方法:创建一个方法,而不提供具体的实现,让派生类去实现该抽象方法
注意:抽象方法只能在抽象类中,且默认为虚方法,
但是在声明抽象方法时不能使用virtual修饰符


属性:访问对象和类的特性的成员
属性不表示存储位置(字段表示一个存储位置)
get访问器:相当于一个无参数的方法,返回值的类型与属性的类型相同
set访问器:相当于返回值为void的方法,该方法只有一个参数,参数的类型要和
属性的类型相同,名称始终为value(value为set访问器隐含的参数)
如果声明访问器使用了static修饰符则为静态属性,
静态属性与实例属性和静态字段与实例字段的差别相似


索引器:对类的字段批量做某种(赋值或者遍历)操作
索引器允许按照索引数组相同的方式索引对象
声明索引器时使用关键字this
索引器的元素不能作为ref或out参数传递
显然索引器也是一种属性,但是和属性有5点差别
1:属性存在一个名称索引器有关键字指定
2:属性可以是静态字段,索引器只能是实例成员
3:属性通过成员访问,索引器通过索引来访问元素
4:属性get访问器是不带参数的方法,而索引器get访问器为
带有参数(索引器的索引)的方法
5:属性的set访问器只带有一个value的方法,而set访问器是除了value
参数之外还带有索引器相关的参数的方法




静态构造函数用来初始化类的静态成员,有些静态成员需要在第一次使用类之前,从外部源
中初始化这些静态字段和属性,在创建第一个实例和引用任何静态成员之前
将自动调用静态构造函数,也可以用于执行只需要执行一次的方法
类的静态构造函数在给定的应用程序中最多执行一次(在第一次创建类的实例或引用任何静态成员之前)
静态构造函数一般用于初始化静态字段和只读字段
静态构造函数没有访问修饰符(默认private)
无法直接调用静态构造函数
在第一次创建类的实例和第一次调用静态成员之前将自动调用静态构造函数




析构函数:释放类的实例的内存
1:没有修饰符,没有参数
2:不能调用
3:只有一个析构函数
4:不能重载和继承






第9章:结构(和类的成员相似)
1:把一系列相关的变量组织成单一实体的类型叫做结构类型
2:使用关键字struct
3:访问修饰符private/public/internal/protected/new(隐藏基类的同名方法)
4:结构和类的区别
1:结构为值类型
2:分配在栈上
3:无参数的构造函数不能声明
4:析构函数不能声明
5:不存在继承,可以实现接口
6:结构默认值:字段本身类型的默认值,类默认值:字段的默认值为null
7:结构实例化时new运算符可以不使用,对象字段具有默认初始值,类必须使用new运算符,且要给每个字段赋初值,否则对象的值为null;例如calss A; A a,a的值为null因为没有实例化


5:在声明结构成员时,不能使用public,protected,internal修饰符,结构不能是抽象的,并且始终是隐
式密封的,在声明结构时不能有abstract,sealed修饰符


注意在结构中可以用override重写从system.value中继承的方法


6:this保留字:保留字只能在实例构造函数,实例方法,实例访问器的块中使用
且表示的是当前实例,类的构造函数中出现this做为一个值类型,表示的是对正在构造对象的引用
但是在结构的构造函数中出现的this作为一个变量类型,表示正在
构造的结构的引用,在结构的方法中出现的this作为一个变量类型它表示的是对调用该方法的结构的引用


注意:在结构中由于this相当于一个变量,因此,可以对this赋值,甚至通过this可能修改其所属结构的值
7:构造函数,不能声明无参的构造函数,可以有有参数的构造函数,因为每个结构都有一个隐式地的无参数默认构造函数,隐式地的无参数默认构造函数将初始化该所有字段的值,如果字段类型为值类型,赋值为类型的默认值,如果字段类型为引用类型,赋值为null








第10章:数组
1:有序的数据集合
2:声明数组语法: type[] arrayName
3:实例化数组才为数组分配内存 
int[] arr;声明了一个数组,没有分配内存
arr = new int[];实例化数组,分配内存
4:数组的初始化:实例化数组后,如果数组没有初始化则每个元素为其类型的默认值
1:直接初始化(没有指定数组的长度)
int[] a = {1,2,3,4,5,6};数组的长度为6
2:实例化赋值+指定的长度
int[] a = new int[6]{1,2,3,4,5,6}
3:实例化赋值+省略长度
int[] a = new int[]{1,2,3,4,5,6}
4:直接设置数组的每一个值
int[] a = new int[6]
a[0] = 1
...
a[5] = 6


5:二维数组
语法:type[,] arrayName
要使用数组的话要实例化数组
int[,] a = new int[2,2]实例化数组
6:多维数组
语法:type[,,] arrayName
要使用数组的话要实例化数组
int[,,] a = new int[2,2,2]实例化数组
7:交错数组:每一行不包含的列数不同
交错数组可以看成是数组的数组
语法:type[][] arrayName
声明一个数组:int[][] arr
实例化数组:arr = new int[10][]因为没有初始化,数组元素为类型默认值
int[][] a = new int[10][]
for(int i =0;i<10;i++)
{
a[i] = new int[i+1];为交错数组的第二维设定长度
}


静态数组System.Array
1:数组的大小不能修改称为静态数组由System.Array类实现
获取一维数组元素的索引:System.Array静态方法IndexOf()和LastIndexOf()
静态方法排序Sort
静态方法反转Reverse
上面的静态方法只能对一维数组
2:动态数组数组的长度可以修改由System.ArrayList类实现
动态数组:存储不同数据类型的数据,保存的是元素的引用而不是元素的具体值
ArrayList list = new ArrayList();创建一个动态数组并实例化该数组




第11章:接口:有时需要某些类具备特定方法和属性为了避免开发者遗漏c#提供了接口
接口定义了类必须包含的部分
声明接口:关键字interface
public interface myInterface{}
接口可以继承接口
接口的访问权限:internal,public,protected,private,new


接口的成员:方法,事件,属性,索引器,默认访问属性public,
但是成员不能加访问修饰符
例如:
public interface Iinterface
{
string Name{get;set;}
string this[int index]{set;get;}
void method();
event EventHandler Print;事件
}
注意:在实现事件时,需要add访问器和remove访问器
add访问器用来注册一个事件
remove访问器用来移除一个事件,其中被注册或移除的事件都用
默认参数value表示
public class Program:Iinterface
{
event EventHandler print;声明事件
event EventHandler Iinterface.Print实现接口事件
{
add{Print+=value;}
remove{Print-=value;}
}
public void F()
{
EventHandler handler = print;
if (handler)
{
handler(this,new EventArgs())
}
}


public calss A{
public A(Program p)
{
Iinterface p1 = (Iinterface )p
p1.Print+=new EventHandler(fun)
}


void fun(object obj,EventArgs e)
{


}
}


}




抽象类与非抽象类的区别
抽象类不能实例化
抽象类不能被密封
抽象类允许包含抽象成员
抽象类派生非抽象类时,非抽象类必须实现(重写)抽象类中的抽象函数


第12章委托和事件
委托和类一样在使用时要声明
声明语法:访问修饰符 delegate 委托类型 委托名
delegate int fun(int,int)
访问修饰符:private,public,internal,protected,new
new:只有在其他类型中声明委托时,才能使用new,表示所声明的委托会隐藏具有相同名称的继承成员


委托实例化
fun = new fun(方法)
构建委托的方法列表+=(向实例的方法列表注册方法)-=(向实例的方法列表移除方法)




事件:它是一种信号机制
声明事件:它包含两个参数,指示事件源的对象源参数和封装事件
的其他任何相关信息的e参数(与该事件相关的信息),其中e参数的类型为System.EventArgs或者从
System.EventArgs派生类的类型
声明事件分为两步:
1:声明事件的委托
public delegate void EventHandler(object sender,EventArgs e)
2:声明事件本身,使用event关键字
public event EventHandler Print;Print事件的名字


声明事件之后事件的默认值为null要为该事件注册方法
注册事件+=
移除事件-=
调用事件之前要判断事件是否为空,如果不为空则调用事件,事件的参数为null




第13章:异常处理
try块:包含发生异常的代码
catch:捕获异常
finally:资源清理操作,不管有没有异常finally都会执行
message和innerException属性是System.Exception类的最常用的属性
message:描叙异常的错误信息
innerException:导致当前异常的exception实例




第14章:泛型:具有占位符(类型参数)的类,结构,接口和方法,两个功能非常相似,但是方法的参数类型不同
1:类型形参是一个简单的标识符,只起到占位符的作用,使用时才指定实际类型(实例化时指定)
2:设置类型形参的约束
设置类型形参的约束使用where上下文关键字指定后面跟一个类型形参和冒号,
再跟一个冒号分隔的列表,列表项可以是类类型,接口类型,甚至是类型形参
还可以是特殊引用类型,值类型,和构造函数约束


常用类型的约束
T:结构 类型参数必须为值类型,但是不能是Nullable类型
T:类  类型参数必须为引用类型
T:new() 类型参数必须具有无参数的公共构造函数,如果该类型参数存在多个约束,则new()必须最后
指定
T:<基类名> 类型参数必须是指定的基类或者派生类
T<接口名称> 类型参数必须是指定的接口实例或者实现指定的接口
T:U T的类型参数必须是U提供的参数或者派生自为U提供的参数
例如
public class Test<T>where T:class new()
{
T类型参数必须是引用类型还有具有公共的无参数的构造函数
}


泛型类的静态字段共享方法比较特殊,只有泛型类和静态字段具有相同类型的类型参数
才能够共享同一个静态字段
例如
public class<T> A
{
public static int count;
public A()
{
count++
}
}
只有类A的泛型参数T为int时实例出来的两个对象共享count
A<int> a = new A<int>() count = 1
A<int> b = new A<int>() count = 2
A<float> c = new A<float>() count = 1这时count=1不是3




泛型方法:可以在类中定义泛型方法
泛型方法和泛型类一样,类型形参可以有约束条件
泛型方法也可以是虚泛型方法,抽象方法和重写方法关键字修饰




第15章:分部类型和可空类型
分部类型:将一个类或者接口,结构可以分成几个部分,由不同人编写,储存在不同源文件中
声明分部类型需要使用partial修饰符,必须在同一个命名空间
注意partial修饰符不能声明委托和枚举
public partial class A
public partial struct atr
public partial interface Iinterface


可空类型:解决了如何辨识和处理不包含值得字段问题
可空类型是一个特殊的值类型,由结构表示,它除了表示基础类型的所有值,还可以是null
可空类型是System.Nullable<T>类型的对象,T必须是非可空值类型
声明可空类型存在两种形式
System.Nullable<T> variable
使用?声明可空类型
T? variable T?是System.Nullable<T>的简写形式
T:表示可空类型的基础类型 ,variable 可空类型变量的名称
可空类型的基础类型不能是可空类型和引用类型只能是
非可空值类型:float,int
非可空值类型的类型参数,即具有strct约束的类型参数
下面声明一个可空类型
int? day
任何可空类型包含两个公共属性
HasValue和Value
HasValue:判断可空类型是否有值
Value:获取可空类型实例的值
可空类型只包含一个方法:GetVlueOrDefault()
获取可空类型的实例的值或默认值
两种重载方式
T GetVlueOrDefault()HasValue属性为true返回实例的值
T GetVlueOrDefault(T defaultValue)HasValue属性为false返回默认值


可空bool类型
3个值false,true,null
两个运算符&和|




第16章:更好的赋值
隐形变量,初始化器,匿名类型,隐形数组


1:隐形局部变量:关键字var不需要指定类型
var day = 1声明隐形局部变量day 从隐形局部变量初始化表达式推导出day的类型为int
声明隐形局部变量4条规则:
1:必须包含初始化表达式
2:不能引用隐形局部变量本身
3:不能是数组初始值设定项 例如var d = {1,2,3,4,5}
4:在编译时编译器能够确定该初始化表达式的类型 var d = null错误的声明


2:对象初始化器:包含一组成员初始值设定项,设定项由{}包围,各个设定项有逗号分隔
Program p = new Program{age=12,name="zs"}
等效Program p = new Program()p.age = 12 p.name = "zs"
集合初始化器包含一组元素初始值设定项,设定项由{}包围,各个设定项有逗号分隔
List<int> a = new List<int>()
a.Add(1)
a.Add(2)
等效于
List<int> a = new List<int>{1,2}




3:匿名类型:由new运算符和对象初始化器共同实现
匿名类型可以将一组只读属性封装到单个对象中,无需显示定义一个类型,类型由编译器生成
由new运算符和对象初始化器组成的表达式叫匿名对象创建表达式
两个匿名类型的属性相同,并且排序相同则可以看成同一个类型


4:匿名数组:由var关键字和匿名数组初始化器共同创建
var arr = new[]{"a","b","c"}数组元素类型必须转换为同一个类型
var arr = new[]{"a",1,2,3,4};编译错误因为元素不能转换为同一类型
如果希望arr隐形数组不产生编译错误,则显示为匿名数组初始化器指定一个类型
var arr = new object[]{"a",1,2,3,4}编译正确


第17章:迭代器,匿名方法,扩展方法
迭代器:产生有序值序列的语句块,使遍历更加简单
使用关键字yield
包含两个特有的语句
yield return语句可以产生迭代的下一个值
yield break语句表示迭代完成
当迭代器执行到yield return语句时,会保存当前位置,如果迭代器再次被调用
将从保存的位置开始执行
迭代器的返回类型必须为(IEnumerable(可枚举接口),IEnumerator(枚举器接口),IEnumerable<T>,IEnumerator<T>)


创建非泛型迭代器:实现IEnumerable接口的GetEnumerator()方法
创建泛型迭代器:实现IEnumerable接口和IEnumerable<T>接口的GetEnumerator()方法


为创建的类对象能够在foreach循环中使用,必须实现IEnumerable接口和
IEnumerator接口的泛型和非泛型
IEnumerator包含两个方法和一个属性
MoveNext方法:将枚举数推进到集合的下一个元素
Reset方法:重置,设置枚举数位于集合中第一个元素之前
Current属性:获取集合中的当前元素
注意:迭代器被创建之后,枚举数定位在集合中第一个元素前,此时,Current属性的值为null


Program p = new Program()
IEnumerator ie = p.GetEnumerator()获取p实例的迭代器
while(ie.MoveNext())
{
}


IEnumerator<T>包含两个方法和一个属性
MoveNext方法:将枚举数推进到集合的下一个元素
Reset方法:重置,设置枚举数位于集合中第一个元素之前
Current属性:获取集合中的当前元素
Dispose()方法:释放实例占有的资源




匿名方法
关键字:delegate,参数列表(可选),和包含在{}中的语句列表


扩展方法:向现有类型添加新的方法
声明扩展方法:需要this修饰符,扩展方法的第一个参数指定该方法所作用的类型
并使用this修饰符作为该参数的前缀
注意:扩展方法必须声明为静态方法,且必须声明在静态类中




第18章lambda表达式和查询表达式
lambda表达式:也是一种匿名方法
语法形式
(intput parameters(输入参数(可选的)))=>expression(表达式或者语句块)
输入参数:
输入参数为1时小括号可以省略
表达式或者语句:


查询表达式:
必须以from子句开始,select或者group子句结束






第19章字符串:
数字格式化采用Axx的形式,A为格式说明符,它是一个字母型字符,xx表示精度,值0-99的整数
常见的格式说明符:C()c/D(d)/E(e)/F(f)/N(n)/P(p)/X(x)


第20章:时间和日期处理
DateTime结构用来表示时间上的某一时刻
常用的格式:
yyyy-MM-dd hh:mm:ss
DateTime结构表示时间间隔
常用的格式:
[-]d.hh:mm:ss.ff
d是天数
ff毫秒




第21章:IO流
文件流:FileStream
内存流:MemoryStream以内存作为支持存储区
文件操作的类File,FileInfo
File为静态类,可以协助创建FileStream
FileInfo:使用时需要实例化FileInfo的对象
目录操作:Directory,DirectoryInfo
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值