c# 入门
程序集
对应于vs中的一个项目工程,是一个单独的程序文件。程序文件分为两类,dll类和exe应用程序
命名空间
和c++的命名空间差不多是一个作用,定义一个作用域。在c#的命名空间中,只能够声明结构体,类,接口,委托或命名空间等类型,但是不能定义这些类型的变量和对象。因为在c#中只能在类里面定义对象。
类型
类型可以分为值类型和引用类型。其中内建的基本类型,枚举和结构体属于值类型,剩余的string,类,接口,委托等都是引用类型。在对象赋值时,只有通过new才是在内存中分配内存空间创建新的对象,否则只是引用的传递。
类
与c++主要有以下区别:
1、关键字class前面可以添加限定符,常用的限定符有下面几个:
1)、abstract:表示这是一个抽象类
2)、partical:表示当前定义只是类的部分定义,在其他地方还有这个类的定义
3)、sealed:表示这个类不能够被继承
2、只能有一个继承类,并且只有公有继承
3、在继承类的后面,可以继承一个或多个接口
4、与c++相比,类的成员更加丰富
1)、增加了属性的成员,其实就是增加对私有成员的访问,私有成员一般变量一般以下划线开头。属性实现对私有成员的访问和赋值以及有效性检查。形式为
///属性没有形参,自动有一个参数value实现对私有变量的赋值,返回值类型就是私有变量的类型
public long Number
{
get{return _num;}///访问值
set{_num = value;}///赋值,也可以不要set,定义一个只读属性
}
2)、类的每个成员前面都有访问权限的关键字,不像c++把具有相同权限的成员写在一起,c#一共有五个访问权限
1))、public:任何程序集的类型都可以访问
2))、protected:任何程序集的这个类的派生类可以访问
3))、internal:同一程序集的类型可以访问
4))、protected internal:同一程序集的这个类的派生类可以访问
5))、private:这能在这个类型的内部访问
定义类的默认权限是internal,类成员的默认类型是private,类实例的默认值是null
3)、事件
限定符 event 委托类型名 事件名;
在这个定义中event与委托类型联系起来,然后委托再与方法联系起来,这样调用事件时,就能这样调用到委托对应的方法。所以要实现一个完整的调用,要完成下列步骤:
1))、声明委托类型,委托的实质其实就是一个函数指针,因此其定义类似于函数方法的定义,它一般有两个参数,第一个参数一般表示发生事件的类的对象,第二个参数一般是一个事件参数。当然有些委托比较简单,这两个参数都没有,只传递了一个具体的参数类型,;事件对象和委托的声明一般是在一个类里面的,示例如下:
public delegate void MyButtonEventHandler(string msg);
internal class KeyInputMonitor { // 创建一个委托,返回类型为void,两个参数 public delegate void KeyDownHandler( object sender, KeyEventArgs e ); // 将创建的委托和特定事件关联,在这里特定的事件为KeyDown public event KeyDownHandler KeyDown; public void Run() { bool finished = false; do { Console.WriteLine( "Input a char" ); string response = Console.ReadLine(); char responseChar = ( response == "" ) ? ' ' : char.ToUpper( response[0] ); switch( responseChar ) { case 'X': finished = true; break; default: // 得到按键信息的参数 KeyEventArgs keyEventArgs = new KeyEventArgs( responseChar ); // 触发事件 KeyDown( this, keyEventArgs ); break; } }while( !finished ); } }
2))、如果需要用到事件参数,就需要定义事件参数类,EventArgs是所有事件参数类的基类
internal class KeyEventArgs : EventArgs { private char keyChar; public KeyEventArgs( char keyChar ) : base() { this.keyChar = keyChar; } public char KeyChar { get { return keyChar; } } }
3))、创建事件对象处理类
internal class EventReceiver { public EventReceiver( KeyInputMonitor monitor ) { // 产生一个委托实例并添加到KeyInputMonitor产生的事件列表中 monitor.KeyDown += new KeyInputMonitor.KeyDownHandler( this.OnKeyDown ); } private void OnKeyDown(object sender, KeyEventArgs e) { // 真正的事件处理函数 Console.WriteLine( "Capture key: {0}", e.KeyChar ); } }
4))、调用过程
public class MainEntryPoint { public static void Start() { // 实例化一个事件发送器 KeyInputMonitor monitor = new KeyInputMonitor(); // 实例化一个事件接收器 EventReceiver eventReceiver = new EventReceiver( monitor ); // 运行 monitor.Run(); } }
事件和委托的区别
1、委托在任何地方都可以被调用,比较灵活
2、事件只能在特定的事件触发函数中被调用,如果控件的事件函数,在其他地方调用会直接报错,它保证了只有在界面上触发消息时,事件才能被调用
参考:http://blog.csdn.net/lulu_jiang/article/details/6451300#comments
4)、索引器
5)、构造函数
构造函数分为静态构造函数和实例构造函数
1))、静态构造函数
静态构造函数与c++的构造函数相比,在函数名的前面多了一个static关键字,虽然可以定义,但是不能显式的调用静态构造函数,它的调用顺序发生在初始化类的静态成员之后,调用类的静态成员函数或实例化类对象之前。
2))、实例构造函数
限定符 构造函数名(参数列表):this(参数列表),base(参数列表)
上面定义跟c++还是有区别的,它可以添加限定符,并且还是调用该类的其他构造函数
6)、析构函数
一般情况下是不需要显示的定义析构函数的,因为会自动释放资源,显示定义析构函数可能会造成资源被释放两次
5、接口
限定符 interface 接口名:继承接口列表
说明
1)、接口不能实例化
2)、接口里面的类成员没有权限类型,并且也没有这些方法的实现
6、关键字
1)、abstract
修饰类表示这是一个抽象类;修饰成员表示这个成员没有实现,必须在派生类中进行实现
2)、as
把一个类型转化为另一个类型,发生错误就返回null,例如
object obj = GetPhotoObj();
PhotoGraph pgObj = obj as PhotoGraph;
3)、base
表示这个类的基类
4)、is
确定一个对象是否可以转化为指定对象,返回值为bool类型
5)、lock
把一个作用域内的语句标记为关键段,表示同一时间只能有一个线程可以执行
lock (this) { }
6)、out
函数参数的修饰符,表示这样的参数会影响实参值,这样的参数不能初始化
7)ref
与out类似,只是ref的参数必须被初始化
ref和out的比较
1、ref和out都是按地址传递。但是out只会传递引用而不传值,就是说该引用对应的值是无法传递到方法内部的,所以out型参数额不用在外面初始化,必须在方法内部进行初始化。而ref则是引用和值都会传递,这就要求ref参数要在调用之前进行初始化。
2、上面原理的不同决定了它们的作用有所不同。out无法传进引用值,所以他的作用相当于方法可以有多个返回值。而ref可以传进值,它的作用相当于对传入参数值的处理过程。
3、ref,out参数方法的定义和使用都要显示的调用其修饰符。
4、虽然ref和out的运行机制不一样,但是它们在编译时却被认为是完全一样的,因此不能重载类型相同,但是ref和out修饰符不同的方法。但是有修饰符和无修饰符的方法则是可以重载的。
5、综上,ref在方法中是可进可出,out是只出不进
8)override
在派生类中重写基类的虚函数
8)、sealed
表示一个类无法被继承,不能修饰抽象类
7、数组
数组array类型属于system.Array的命名空间,是引用类型,而ArrayList则属于System.Collections
8、常见的命名空间
1)System.Collections
这个命名空间提供了常用的数据结构,如果列表arraylist,堆栈,散列表,字典等等。另外两个字命名空间Generic和ObjectModel提供了泛型数据结构的支持,就是c++里面的类模板,可以指定具体的数据类型。