类似于Java虚拟机,它不但是Intrrnet上运行的应用程序更容易被开发,而且也可用于开发运行于Windows桌面上的传统业务应用程序。它为创建、部署以及管理安全、强大、高效的应用程序提供了前所未有的最大支持。
两个主要组件:
公共语言运行时(CLR)Common Language Runtime
统一的类库集
.NET Farmework是一个创建、部署和运行应用程序的多语言平台环境,
.Net Farmework类库(FCL)
公共语言运行时(CLR)
操作系统
.NET Framework有框架类库(FCL)和公共语言运行时(CLR)这两组建组成。
.NET Framework的 组件及其要素:
.NET Framework类库:Web Forms ; web Services ;WinForms
ADO.NET和XML类
基本框架类
CLR: CLS ;CTS
其中:
Web Forms 是提供一组网页设计的类,Web Forms与HTML表单很相似。
Web Services包括一组设计Web服务的类,可用来构造网络服务的应用程序。
WinForms提供一组windows的窗体应用程序设计和开发的类。
ASP.NET提供一组用语创建WEB应用程序的类。
ADO.NET提供一些可与数据库运行交互的类。
XML类启动用XML操纵、搜索和转换。
基本框架类 提供基本功能,如输入输出、字符串操纵、安全性管理和网络通信等。
通用语言规范(CLS)规定了使用所有语言都必须遵循的基本语言功能的公共子集。
公共类型系统(CTS)描述如何在运行时声明、使用和管理像类、结构、枚举、接口等类型,从而便于在各语言之间使用这些类型。
( CLR ):CLR为与.NET Framework配合使用的任何语言提供了诸如内存管理、安全性和错误处理等功能。.NET 总的所有代码都有CLR管理。因此称为“托管代码”
MSIL :中间语言,当编译用兼容.NET的语言编写代码时,输出的代码为MSIL,再有MSIL转换为CPU能识别的代码,这个过程称为“即时”编译或JIT
通用语言规范( CLS )和公共类型系统( CTS )
CLS :语言通用规范,.NET Framework语言中互操作性的功能,所有.NET 语言都应该遵循次规则才能创建与其他语言可互操作的应用程序。但是,为了是各语言可以互操作,只能使用具有CLS中列出的功能对象,这些功能统称为CLS兼容的功能。
命名空间用来将具有相关功能的相似类在逻辑上进行分组。命名空间还可以用来对相似数据类型进行分组。
在.NET Framework中,说有命名空间基本上都是从称为System的公共命名空间形成的。System命名空间称为公共命名空间。
System.Data 处理数据访问和管理;在定义ADO.NET技术中起重要作用
System.IO 管理对文件和流的同步和异步访问
System.Windows 处理基于穿体的Windows创建
System.Reflection 包含用语从程序集里读取元数据的类
System.Threading 包含用语多线程编程的类
System.Collections 包含不同的接口和类,这些接口和类用来定义不同的对象
using System;
namespace Notepad
{
class HelloWorld
{
public static void Main()
{
Console.WriteLine(“Hello World”);
Console.ReadLine();
}
}
}
说明:class定义类; Main()为程序的入口 M必须大写;Console.WriteLine()为打印输出; Console.ReadLine()读取输入的字符,文件保存为.cs格式:HelloWorld.cs
在命令提示符窗口下编译:csc HelloWorld.cs 然后运行HelloWorld
★ C#中的数据类型
C#数据类型 大小 默认值
int 有符号的32位整数 0
float 32位浮点数,精确到小数点后7位 0.0F
double 64位浮点数,精确到小数点后15~20位 0.0D
decimal 128位浮点数,精确到小数点后28~29位 0.0M
byte 无符号的8位整数 0
short 有符号的16位整数 0
long 有符号的64位整数 0L
bool 布尔值,true或false false
string Unicode字符串 -
char 单个Unicode字符 ‘/0’
一、声明C#中的变量和常量
1.C#中的变量
语法:访问修饰符 数据类型 变量名称;
命名规范:
内联变量(在方法内声明的变量)必须一骆驼命名法声明,而类变量(也称为成员变量)也必须以骆驼命名`法声明,但应以一个下划线开头。
不应使用匈牙利命名法命名变量
避免使用单个字符作为变量名
2.C#中的常量
以const关键字进行声明,后面接C#支持的数据类型之一和赋值语句。
语法:访问修饰符 const 数据类型 常量名称 = 常量值;
编译运行时常量的值永远不会改变,运行时常量可能具有不同值
const指定后不能改变
readonly运行时常量可能具有不同的值
命名方法:
带有私有访问修饰符的常量必须以骆驼命名法声明,并以一个下划线开头。
带有公共修饰符和受保护修饰符的常量必须以帕斯卡命名法生命。
二、C#数据类型的分类
值类型:存储在内存的堆栈中,从堆栈中可以快速访问这些数据,因此,值类型表示实际数据。
引用类型:表示指向存储在内存中的数据的指针或引用。包括:类、接口、数组、字符串。
三、装箱和拆箱
装箱是允许值类型作为引用类型进行处理的过程,而拆箱是允许引用类型作为值类型进行处理的过程。
利用装箱和拆箱的功能,拥护可通过允许值类型的任何值与Object类型的值相互转换,将值类型与引用类型链接起来。
装箱:
int val = 100;
object obj = val;
拆箱:
int num = (int)obj
四、C#中的运算符和表达式
1.运算符的分类:
算术运算符:
+ 用于执行加法运算,如果操作的字符串,则做为字符串的连接运算符。
- 减法运算
* 乘法运算
/ 除法运算,并得到商
% 出发运算后的取余
++ 用语操作数加1
-- 用语操作数减1
~ 将一个数按位取反
比较运算符:
> 检查一个数是否大于另一个数
< 检查一个数是否小于另一个数
>= 检查一个数是否大于等于另一个数
<= 检查一个数是否小于等于另一个数
== 检查两个数是否相等
!= 检查两个数是否不等
三元运算符:
?: 判断?前的表达式是否为真,结果为:前的值,如果为假,结果为:后的值
赋值运算符:
= 给变量赋值
逻辑运算符:
&& 逻辑与,检查表达式是否都为真
|| 逻辑或,检查表达式中至少一个为真
! 逻辑非,检查表达式取反后是否为真
强制转换运算符:
() 将操作数强制转换为给顶的数据类型
成员访问运算符:
. 访问数据结构的成员
快捷运算符:
+= 如5+=5; 等于 x=x+5;
-= 如5-=5; 等于 x=x-5;
*= 如5*=5; 等于 x=x*5;
/= 如5/=5; 等于 x=x/5;
%= 如5%=5; 等于 x=x%5;
2.运算符的优先级:
优先级(1为最高级) 运算符 结合
1 () 从左到右
2 ++/-- 从右到左
3 * / % 从左到右
4 * - 从左到右
5 < > <= >= 从左到右
6 = != 从左到右
7 && 从左到右
8 || 从左到右
9 = += -= *= /= %= 从右到左
五、C#中的选择语句
1、if else
语法:
if(表达式)
{
语句块
}
else
{
语句块
}
2、switch case
语法:
switch(表达式)
{
case 值1:语句;bread;
case 值2:语句;bread;
case……;
default:语句;break;
}
六、C#中的循环结构
1.while
语法:
while(条件)
{
语句块
}
先判断条件是否为真,为真则执行语句块,否则不执行
2.do……while
语法:
do
{
语句块
} while(条件);
先执行语句块,后判断条件是否为真,为真则执行语句块,否则不执行
3.for
语法:
for(初始值;条件;增/减)
{
语句块
}
4.foreach
语法:
foreach(类型 元素(变量命) in 集合或者数组)
{
语句块
}
七、数组
语法:数据类型[数组的大小或容量] 变量名;
声明数组和初始化的几种方法:
一维:
string[] arr = {“asdf”,”sdf,”sdf”,……};
string[] arr = new string[10];
int[] intarr = new int[4]{0,1,2,3};
int[] intarr = {0,1,2,3};
二维:
int[,] arr = {{1,1},{2,3},……};
int[,] arr = new int[5,3];
八、结构
C#的结构可以在其内部定义方法:
语法:
struct StructName // struct为声明结构的关键字
{
public int structDataMember;
//结构中显示声明的构造函数必须带有参数
public void StructMethod(参数列表)
{
//实现
}
}
机构命名的编码标准:
结构必须以帕斯卡命名法声明
用名词或名词短句作为结构名称
九、枚举(Enum,Enumerator的缩写)
■什么是枚举?
枚举是一组已命名的数值常量,它们有助于定义具有一组特定值的数据类型。
C#中的枚举与C中的枚举一样,包含与值关联的数字。默认状态下,将0赋值给枚举对象的第一个元素,然后对每个后续的枚举元素按1递增。但是,也可以在初始化阶段将其指定为其他值。枚举元素默认的基础类型为 int
示例:(MSDN中的)
using System;
public class EnumTest
{
enum Days
{
Sat=1,
Sun,
Mon,
Tue,
Wed,
Thu,
Fri
};
public static void Main()
{
int x = (int) Days.Sun;
int y = (int) Days.Fri;
Console.WriteLine("Sun = {0}", x);
Console.WriteLine("Fri = {0}", y);
}
}
输出
Sun = 2
Fri = 7
注意:如果从 Sat=1 中移除初始值设定项,结果将是:
Sun = 1
Fri = 6
因为默认的是0
枚举的命名编码标准:
枚举必须以帕斯卡命名法声明
枚举符中的可选项必须以帕斯卡命名发声明
对象是包含数据和操作的实体,它既定义数据元素,又定义可应用这些数据元素的操作。
类是对一组具有相同属性和行为的对象的描述,类的内容称为类的成员。
声明类的语法:
访问修饰符 class 类名
{
//类的主体
}
给类命名应使用帕斯卡命名法,确保类的名称是一个名词。
类的主题包含 成员变量和成员方法
声明成员变量语法:
访问修饰符 数据类型 成员变量名;
编码惯例:
公共成员变量、受保护成员变量和内部成员变量应使用帕斯卡命名法。
如: public string Name;
私有成员变量应使用骆驼命名法,并以下划线开头。
如: private string _name;
创建类的实例或对象,用C#的net关键字。
访问修饰符 说明
public 可被所属类的成员以及不属于类的成员访问
internal 可被当前程序集访问
protected 可被所属类或派生自所属类的类型访问
private 仅所属类的成员才可以访问
如果对类不指定访问修饰符,则类的默认访问修饰符为 internal ,但是类成员的默认访问修饰符为 private
1 、什么是构造函数
构造函数是类中的一中特殊方法,每次创建类的实例时都会调用此方法。
构造函数一般用来自动初始化成员变量,但也可以根据需要执行其他的动作
构造函数与类同名,不返回任何值
2. 声明构造函数的语法:
访问修饰符 类名()
{
//构造函数的主体
}
没有参数的构造函数为默认构造函数,这种构造函数不接受任何参数。
如果类未定义默认构造函数,运行库将自动提供默认构造函数。
3. 带参数的构造函数
访问修饰符 类名(参数)
{
//构造函数的主体
}
4. 什么是析构函数
析构函数是C#的另一种特殊方法,用语执行清楚操作。析构函数不接受任何参数,也不带任何访问修饰符,析构函数主体包括的一些代码通常用于关闭有实例打开的数据库、文件或网络连接等。
注意:
一个类只能有一个析构函数。
析构函数不能重载。
析构函数不能显示或手动调用,只能有垃圾回收器自动调用。
语法:
~类名()
{
//析构函数的主体
}
1 、声明方法
访问修饰符 返回值类型 方法名(参数)
{
//方法主体
}
注意:
如果不返回任何值,则返回值类型为 void ,参数列表是由逗号分割的零个或多个变量声明列表,它是可选的。
默认的访问修饰符为 private
编码惯例:
给成员方法命名应使用帕斯卡命名法,请确保方法的名称为动词或动词与对象组合。
2 、调用方法
调用C#方法首先要创建对象实例,在用成员访问运算符点来调用方法
如:对象名 . 方法名 ([ 参数列表 ]);
在方法内使用 return [ 表达式 ]语句用语将控制权交回调用程序。
3. 方法重载
方法共用一个名称但对不同数据执行相似的功能,这种概念称为方法重载,不同的方法根据方法签名来识别,方法签名包括对方法的声明。每个重载方法的方法签名都应该是唯一的。
如下:
……
Class Books
{
……
void PayBill(int indix)
{
//方法主体
}
void PayBill(string name)
{
//方法主体
}
void PayBill(int indix,string name)
{
//方法主体
}
}
注意:
可根据不同数量的参数来重载方法,每个被重载的方法都有不同的参数
可根据不同类型的参数来重载方法,参数的数量保持不变。
4 、静态方法
静态方法就是一个类的所有实例共享的方法
语法:
访问修饰符 static 返回值类型 方法名(参数列表)
说明:
访问静态方法的时候不需要创建类的实例,采取“类名.方法名”即可,Console.Write()就是Console类的一个静态方法。
命名空间是为了避免名称冲突和有助于组织代码,在代码中使用命名空间将降低在其他应用程序中重用此代码的复杂性。命名空间相当于规定了不同的范围,在不同的范围内允许有相同的名称,用命名空间方式处理名称冲突的问题,使程序更简洁‘更有条件和更有结构性。
语法:
namespace 命名空间的名称
{
//该命名空间的所有类都放在这里。
}
编码惯例:
给命名空间命名应使用帕斯卡命名法。
1、继承C#中的类:C#不支持多重继承,C#类始终继承自一个基类(如果未在声明中指定一个基类,则继承自System.Object)。
派生类继承基类的语法如下:
using System;
public class Person
{
//这是基类
}
public class Student:Person
{
//这是派生类
}
注:派生类继承基类时用“:”符号连接,派生类继承基类的所有非私有成员变量和方法。
2、调用基类的构造函数:
如果对类没有定义显式构造函数,则编译器将提供默认的构造函数,以初始化这些类的成员字段。但是,如果显式添加了构造函数,就可以有效控制整个构造过程。
示例:
using System;
namespace Jicheng
{
//基类
public class Person
{
public string _name;
public uint _age;
//基类的构造函数
public Person(string name,uint age)
{
this._name = name;
this._age = age;
//打印输出
Console.WriteLine(_name);
Console.WriteLine(_age);
}
}
//派生类
public class Student:Person
{
private uint _id;
//派生类构造函数并调用基类构造函数用“:base”
public Student(string name,uint age uint id):base(name,age)
{
this._id = id;
Console.WriteLine(_id);
}
}
public class Exercise
{
[STAThread]
static void Main(string[] args)
{
// 构造 Student
Student objstudent=new Student(“XYZ”,45,001);
}
}
}
注:派生类通过使用 :base ()语法可以显式调用基类的构造函数。在必要的情况下,可以利用它来初始化字段。
关键字: override
override 关键字用语修改方法,具有 override 关键字修饰符的方法是对基类中同名方法的新实现,基类中的同名方法必须声明为 virtual 或 abstract 类型。给基类中的方法添加 virtual 关键字表示可以在派生类中重写它的实现。
1 、默认的 C# 方法并非 virtual ,因此不能重写。
2 、基类方法的可访问级别并不因重写它的方法而改变,他们的访问修饰符相同。
3 、 new 、 static 和 virtual 关键字不能与 override 访问修饰符一同使用
关键字: virtual
C# 中提供 virtual 关键字,用语将方法定义为支持多太,用于对一个类中可修改的方法的声明,这种方法称为虚拟方法,字类可以使用 override 关键字自由实现它们各自版本的虚拟方法
语法:
[ 访问修饰符 ] virtual [ 返回值类型 ] 方法名称( [ 参数列表 ] )
{
// 虚拟方法的实现
}
1 、virtual访问修饰符不能与static和override等访问修饰符一同使用
2 、调用虚拟方法,在运行时系统会自动检查,以确定调调用了哪一个实现方法。
关键字: new
new 访问修饰符用于显式隐藏继承自基类的成员,如果派生类成员与基类成员名称相同,new会将派生类成员识别为一个全新成员。
1 、在一个方法中同时使用new和override将会出错。
2 、new访问修饰符的真正目的是为了隐藏基类方法。
3 、如果将一个方法生命为new,它实际上并没有隐藏基类方法,并且编译器也产生了警告,这时应该删除new。
什么是抽象类: 不能被实例化的类称为抽象类,抽象类是派生类的基类。
关键字: abstract
语法:
abstract class 类名
{
…………
}
1 、一个抽象类可以同时包含抽象方法和非抽象方法。
2 、抽象方法只在派生类中真正实现,这表明抽象方法只存放函数原型,不涉及主体代码,
3 、派生自抽象类的类需要实现其基类的抽象方法,才能实例化对象。
4 、使用override关键子可在派生类中实现抽象方法,经override声明重写的方法称为重写基类方法,其签名必须与override方法的签名相同。
示例:
using System;
namespace Example_5
{
// 抽象类
abstract class ABC
{
//抽象方法
public abstract void Afunc();
}
//派生类
class Derv:ABC
{
//实现抽象类中的抽象方法
public override void Afunc()
{
Console.WriteLine(“实现抽象方法”);
}
}
public class Test
{
static void Main(string[] args)
{
Derv obj=new Derv();
obj.Afunc();
}
}
}
5、基类实现抽象类,则派生类不需要重新实现该抽象类。
6、抽象类并不仅仅只是一种实现技巧,它更代表一种抽象的概念,从而为所有的派生类确立一种约定。
关键字: interface
语法:
修饰符 interface 接口名
{
// 接口主体
}
1 、一个接口就相当于一个抽象类,但是它不能半喊任何实现方法。
2 、接口的每种方法都必须在派生类中实现。
3 、接口有时候可以看成是类的模具,它指明一个类该提供哪些内容。
4 、接口主体只限于方法、索引器、属性的声明。
5 、接口中不能包含字段、构造函数和常量等。
6 、接口成员是隐式公开的,如果对其显式指定访问级别,就会出现编译器错误。
7 、在接口中不能实现任何方法,属性或者索引器。
8 、在指定方法时,只需给出返回类型、名称和参数列表,然后以分号结束。
9 、实现接口的语法与实现继承一样,都用冒号“:”
示例
interface Icustomer
{
………………
}
public class MyClass: Icustomer
{
………………
}
10 、接口中的方法不能重写,只能实现。
11 、
编码标准:
接口名称需始终冠以大写字母 I
C# 中 多重接口的实现,弥补了C#只能单一继承,不能多重继承弱点。
语法示例:
public intetface IName
{
void Name();
}
public interface IAge
{
void Age();
}
public class Consoleshow: IAge, IName
{
public void Name()
{
//具体实现
}
public void Age()
{
//具体实现
}
}
如果 两个接口中有完全相同的签名,那么可以用“接口名.方法名”的方法显式的来实现接口。
示例:
public interface Iname
{
void Test();
}
public interface Iage
{
void Test();
}
public Test: Iname, Iage
{
void Iname Test()
{
// Iname 借口的实现
}
void Iage Test()
{
// Iage 借口的实现
}
}
通过合并其他接口,也可以新建接口。用于合并接口的语法于继承的语法非常相似,只是前者可以将多个接口合并成一个。一个类要实现一个接口,必须为基接口和派生借口的所有成员编写代码。