一、 打印
Console.Write(); //输出后不换行
Console.WriteLine(); //输出后换行
二、 C#程序结构
命名空间(namespace),一个class,class方法,class属性,一个Main方法,语句,表达式,注释
namespace HelloWorldApplication {
class HelloWorld{
static void Main(String[] args){
Console.writeLine("Hello World");
Console.ReadKey();
}
}
}
2.1注意
C#是大小写敏感的
所有的语句和表达式以分号结尾
文件名可以不同于类名
程序的执行从Main方法开始
编译和执行
1)在vs中点击Run按钮或者按下F5键来运行程序
2)命令提示符工具,定位到文件所保存的目录CSC helloworld来执行程序
三、C#的数据类型
3.1值类型
bool,byte,char,double,float,int
3.2引用类型
当一个值类型转换为对象类型时,被称为装箱,当一个对象类型转换为值类型时,被称为拆箱
实例:
int val = 8;
object obj = val;//整型数据转换为了对象类型(装箱)
拆箱:之前由值类型转换而来的对象类型再转回值类型, 实例:
int val = 8;
object obj = val;//先装箱
int nval = (int)obj;//再拆箱
只有装过箱的数据才能拆箱
3.3 动态类型
可以存储任何类型的值在动态数据类型中,与对象类型相似,但对象类型检查在编译时发生的,而动态类型变量的类型检查是在运行时发生的
3.4字符串类型
允许给变量分配任何字符串值
可以用@'<script type='text/javaScript'></script>'
3.5指针类型
声明指针的语法
type* identifier;
四、C# 类型转换
类型转换从根本上说是类型铸造,或者说是把数据从一种类型转换为另一种类型,在C#中,类型铸造有两种形式:
1)隐式类型转换-这些转换是C#默认的以安全方式进行的转换,不会导致数据丢失。例如,从小的整数类型转换为大的整数类型,从派生类转换为基类
2)显示类型转换-强制类型转换,显示转换需要强制转换运算符,而且强制转换会造成数据丢失
double d = 56.34
int i;
i=(int)d;
4.1 类型转化的方法
ToBoolean,转化为布尔型
ToByte,转化为字节型
ToChar,转化为Unicode字符类型
ToDateTime,转换为日期-时间结构
ToDecimal,把浮点型或者整数类型转换为十进制类型
ToDouble,转换为双精度类型
ToInt16,转换为16位整数类型
ToInt32,转换为32位整数类型
4.2 类型之间的转换-Convert和Parse
string locstr=123.ToString();
int i=Convert.ToInt16(locstr);
int ii=int.Parse(locstr);
五、变量的定义
int i,j,k;
六、常量
常量是固定值,程序执行期间不会改变,常量可以是任何数据类型。
6.1整数常量
整数常量可以是十进制数,八进制数,或者十六进制数的常量
6.2 定义常量
常量使用const关键字来定义的
const double pi=3.1415926
字符常量
字符常量是在单引号中,一个字符常量可以是一个普通的字符,一个转义序列,或者一个通用字符
字符串常量
字符串常量在双引号中,或者在@""中,字符串常量包含的字符与字符常量相似
七、运算符
7.1算数运算符
- +把两个操作符相加
- 从第一个操作数减去第二个操作数
- / 分子除以分母
- % 取模运算符,整除后的余数
- ++ 自增运算符
- -- 自减运算符
7.2 关系运算符
- == 检查两个操作符的值是否相等
- != 检查两个操作数的值是否相等
-
检查左操作数的值是否大于右操作数
- < 检查左操作数的值是否小于右操作数
-
= 检查左操作数的值是否大于等于右操作数
- <= 检查左操作数的值是否小于等于右操作数
7.3 逻辑运算符
- && 逻辑与运算符,如果两个操作数都非零,则条件为真
- || 逻辑或运算符,如果两个操作数有一个非零,则条件为真
- ! 逻辑非运算符 用来逆转操作符的逻辑状态
7.4 位运算符
- & 二进制与运算
- | 二进制或运算
- ^ 二进制异或运算
- ~ 按位取反
- << 二进制左移
-
二进制右移
7.5 赋值运算符
- = 简单的赋值运算符
- += 加且赋值运算符
- -= 减且赋值运算符
- *= 乘且赋值运算符
- /= 除且赋值运算符
- %= 求模且赋值运算符
- <<= 左移且赋值运算符
-
= 右移且赋值运算符
- &= 按位与且赋值运算符
- |= 按位或且赋值运算符
- ^= 按位异或且赋值运算符
7.6 其他运算符
sizeof():返回数据类型的大小
typeof():返回class的类型
&:返回变量的地址
*:变量的指针
is:判断变量是否为某一类型
as:强制转换,即使转换失败也不会抛出异常
八、 封装
封装被定义为‘把一个或多个项目封闭在一个物理的或者逻辑的包中’,在面向对象程序设计方法论中,封装是为了防止实现细节的访问
C#封装根据具体的需要,设置使用者的访问权限,并通过访问修饰符来实现
8.1 访问修饰符
- public 访问修饰符
允许一个类将其成员变量和成员函数暴露给其他的函数和对象,任何共有成员可以被外部的类访问 - Private 访问修饰符
private访问修饰符允许一个类将其成员变量和成员函数对其他函数和对象进行隐藏,只有同一个类中的函数可以访问他的私有成员,即使是类的实例也不能访问他的私有成员 - protected
protected访问修饰符允许子类访问他的基类的成员变量和成员函数 - internal
internal访问说明符允许一个类将其成员变量和成员函数暴露给当前程序中的其他函数和对象 - protected internal
protected internal 访问修饰符允许在本类,派生类或者包含该类的程序集中访问
九、 方法
每一个C#程序至少有一个带有Main方法的类
9.1 定义方法
访问修饰符 返回类型 方法名称 (参数列表){方法主体}
9.2 调用方法
using System;
namespace CalculatorApplication
{
class NumberManipulator
{
public int factorial(int num) {
int result;
if (num == 1)
{
return 1;
}
else
{
result = factorial(num - 1) * num;
return result;
}
}
static void Main(string[] args)
{
NumberManipulator n = new NumberManipulator();//调用 factorial 方法
Console.WriteLine("6 的阶乘是: {0}", n.factorial(6));
Console.WriteLine("7 的阶乘是: {0}", n.factorial(7));
Console.WriteLine("8 的阶乘是: {0}", n.factorial(8));
Console.ReadLine();
}
}
}
9.3 参数传递
- 值参数,这种方式复制参数的实际值给函数的形式函数,实参和形参使用的是两个不同内存的值,当形参的值发生改变时,不会影响实参
- 引用传递参数,是一个对变量的内存位置的引用,当按引用传递参数时,与值参数不同的是,他不会为这些参数创建一个新的存储位置。引用参数表示与提供给方法的实际参数具有相同的内存位置,使用ref关键字声明引用参数
public void swap(ref int x,int y)
- 按输出传递参数,return语句可用于只从函数中返回一个值,但是可以使用输出参数来从函数中返回两个值。输出参数会把方法输出的数据赋给自己,其他方面与引用参数相似
using System;
namespace CalculatorApplication
{
class NumberManipulator
{
public void getValue(out int x )
{
int temp = 5;
x = temp;
}
static void Main(string[] args)
{
NumberManipulator n = new NumberManipulator();/* 局部变量定义 */
int a = 100;
Console.WriteLine("在方法调用之前,a 的值: {0}", a);
n.getValue(out a);
Console.WriteLine("在方法调用之后,a 的值: {0}", a);
Console.ReadLine();
}
}
}
十、 可空类型(Nullable)
可空类型可以表示其基础值类型正常范围内的值,再加上一个null值
十一、 数组
数组是一个存储相同类型元素的固定大小的顺序集合。数组是用来存储数据的集合,通常认为数组是一个同一类型变量的集合
11.1声明数组
double [] balance;
- double,用于指定被存储在数组中的元素的类型
- [],指定数字的秩(数组的大小)
- balance,指定数组的名称
11.2 初始化数组
声明一个数组不会在内存中初始化数组,当数组是一个引用类型,所以需要使用new关键字来创建数组的实例
double [] balance=new double[10];
十二、 string类的方法
- Compare(),比较两个指定的string对象
- Concat(),连接两个string对象
- Contains(),返回一个表示指定string对象是否出现在字符串中的值
- Copy(),创建一个与指定字符串具有相同值的新的string对象
- CopyTo(),从string对象的指定位置开始复制指定数量的字符到Unicode字符数组中的指定位置
- EndsWith(),判断string对象的结尾是否匹配指定的字符串
- Equals(),判断两个指定的string对象是否具有相同的值
- Format(),把指定字符串中一个或多个格式项替换为指定对象的字符串表示
- indexOf(),返回指定字符串在该实例中第一次出现的索引
- indexOfAny(),返回某一个指定的Unicode字符数组中任意字符从该实例中指定字符位置开始搜索第一次的索引
- Insert(),返回一个新的字符串,指定的字符串被插入在当前string对象的指定索引位置
- Join(),连接一个字符数组中的所有元素,使用指定的分隔符分隔每个元素
- Remove(),移除当前实例中的所有字符,从指定位置开始
- Replace(),把当前 string 对象中,所有指定的 Unicode 字符替换为另一个指定的 Unicode 字符,并返回新的字符串。
- split(),返回一个字符串数组,包含当前的string对象中的子字符串,子字符串是使用指定的Unicode字符数组中的元素进行分隔
- StartsWith(),判断字符串实例的开头是否匹配指定的字符串
- ToCharArray(),返回一个带有当前string对象中所有字符的Unicode字符数组
- ToLower(),把字符串转换为小写并返回
- ToUpper(),把字符串转换为大写并返回
- Trim(),移除当前String对象中的所有前导空白字符和后置空白字符
十三、 结构
结构是值类型结构,它使得一个单一变量可以存储各种数据类型的相关数据,定义结构必须使用struct,struct语句为程序定义了一个带有多个成员的新的数据类型
struct Books
{
public string title;
public string author;
public string subject;
public int book_id;
}
13.1 结构的特点
- 结构可带有方法,字段,属性,运算符方法和事件
- 结构可定义构造函数,但不能定义析构函数。不能为结构定义默认的构造函数,默认的构造函数是自动定义的,且不能改变
- 与类不同,结构不能继承其他的结构或类
- 结构不能作为其他结构或类的基础结构
- 结构可实现一个或者多个接口
- 结构成员不能指定为abstract,virtual或protected
- 当使用new操作符创建一个结构对象时,会调用适当的构造函数来创建结构,与类不同,结构可以不使用New操作符即可被实例化
- 如果不使用New操作符,只有在所有的字段都被初始化之后,字段才被赋值,对象才被使用
using System;
struct Books
{
public string title;
public string author;
public string subject;
public int book_id;
};
public class testStructure
{
public static void Main(string[] args)
{
Books Book1; /* 声明 Book1,类型为 Book /
Books Book2; / 声明 Book2,类型为 Book */
Book1.title = "C Programming";
Book1.author = "Nuha Ali";
Book1.subject = "C Programming Tutorial";
Book1.book_id = 6495407;
Book2.title = "Telecom Billing";
Book2.author = "Zara Ali";
Book2.subject = "Telecom Billing Tutorial";
Book2.book_id = 6495700;
Console.WriteLine( "Book 1 title : {0}", Book1.title);
Console.WriteLine("Book 1 author : {0}", Book1.author);
Console.WriteLine("Book 1 subject : {0}", Book1.subject);
Console.WriteLine("Book 1 book_id :{0}", Book1.book_id);
Console.WriteLine("Book 2 title : {0}", Book2.title);
Console.WriteLine("Book 2 author : {0}", Book2.author);
Console.WriteLine("Book 2 subject : {0}", Book2.subject);
Console.WriteLine("Book 2 book_id : {0}", Book2.book_id);
Console.ReadKey();
}
}
十四、 枚举
枚举是一组命名整型常量,使用enum关键字声明,C#枚举是值数据类型,换句话说,枚举包含自己的值,且不能继承或传递继承
14.1声明变量
enum <enum_name>(指定枚举的类型名称)
{
enumeration list是一个用逗号分隔的标识符列表
}
十五、 继承
继承是面向对象程序设计中最重要的概念之一,当创建一个类时,程序员不需要完全重新编写新的数据成员和成员函数,只需要设计一个新的类,继承了已有的类的成员即可
15.1 基类和派生类
一个类可以派生自多个类或接口,这意味着它可以从多个基类或接口继承数据和函数.
using System;
namespace InheritanceApplication
{
class Shape
{
public void setWidth(int w)
{
width = w;
}
public void setHeight(int h)
{
height = h;
}
protected int width;
protected int height;
}
class Rectangle: Shape
{
public int getArea()
{
return (width * height);
}
}
class RectangleTester
{
static void Main(string[] args)
{
Rectangle Rect = new Rectangle();
Rect.setWidth(5);
Rect.setHeight(7);
Console.WriteLine("总面积: {0}", Rect.getArea());
Console.ReadKey();
}
}
}
15.2 基类的初始化
派生类继承了基类的成员变量和成员方法,因此父类对象应在子类对象创建之前被创建
using System;
namespace RectangleApplication
{
class Rectangle
{
protected double length;
protected double width;
public Rectangle(double l, double w)
{
length = l;
width = w;
}
public double GetArea()
{
return length * width;
}
public void Display()
{
Console.WriteLine("长度: {0}", length);
Console.WriteLine("宽度: {0}", width);
Console.WriteLine("面积: {0}", GetArea());
}
}//end class Rectangle
class Tabletop : Rectangle
{
private double cost;
public Tabletop(double l, double w) : base(l, w)
{ }
public double GetCost()
{
double cost;
cost = GetArea() * 70;
return cost;
}
public void Display()
{
base.Display();
Console.WriteLine("成本: {0}", GetCost());
}
}
class ExecuteRectangle
{
static void Main(string[] args)
{
Tabletop t = new Tabletop(4.5, 7.5);
t.Display();
Console.ReadLine();
}
}
}
15.3 多重继承
多重继承是一个类别可以同时从多于一个父类继承行为与特征的功能,与单一继承相对,单一继承指一个类别可以继承自一个父类
C#不支持多重继承,但是可以通过接口来实现多重继承
using System;
namespace InheritanceApplication
{
class Shape
{
public void setWidth(int w)
{
width = w;
}
public void setHeight(int h)
{
height = h;
}
protected int width;
protected int height;
}
public interface PaintCost
{
int getCost(int area);
}
class Rectangle : Shape, PaintCost
{
public int getArea()
{
return (width * height);
}
public int getCost(int area)
{
return area * 70;
}
}
class RectangleTester
{
static void Main(string[] args)
{
Rectangle Rect = new Rectangle();
int area;
Rect.setWidth(5);
Rect.setHeight(7);
area = Rect.getArea();
Console.WriteLine("总面积: {0}", Rect.getArea());
Console.WriteLine("油漆总成本: ${0}" , Rect.getCost(area));
Console.ReadKey();
}
}
}
十六、C#多态性
多态性意味着多种形式,在面向对象编程范式中,多态性往往表现为“一个接口,多个功能”,多态性可以是静态的或动态的,在静态多态性中,函数的响应式是在编译时发生的,在动态多态性中,函数的响应是咋运行时发生的
16.1 静态多态性 函数重载
函数的定义必须彼此不同,可以是参数列表中的参数类型不同,也可以是参数个数不同,不能重载只有返回类型不同的函数声明
16.2动态多态性
C#使用关键字abstract创建抽象类,用于提供接口的部分类的实现
抽象类的规则:
- 不能创建一个抽象类的实例
- 不能在一个抽象类外部声明一个抽象方法
- 通过在类定义前面放置关键字sealed,可以将类声明为密封类,当一个被声明为sealed时,他不能被继承,抽象类不能被声明为sealed
关键字virtual声明虚方法:用于方法在继承类中的实现(在不同的继承类中有不同的实现)
virtual和abstract - virtual修饰的方法必须有实现
+virtual可以被子类重写,而abstract必须被子类重写
如果类成员被abstract修饰,则该类前必须添加abstract,因为只有抽象类才可以有抽象方法
+无法创建abstract类的实例,只能被继承无法实例化
重载和重写
重载是提供了一种机制,相同函数名通过不同的返回值类型以及参数来区分的机制
重写是用于重写基类的虚方法,这样在派生类中提供一个新的方法。
十七、接口
- 接口定义了所有类继承接口应遵循的语法合同
- 接口定义了属性,方法和事件,这些都是接口的成员。接口只包含了成员的声明,成员的定义是派生类的责任,接口提供了派生类应遵循的标准结构
- 接口由interface关键字声明,默认为public
- 如果一个接口继承其他接口,那么实现类或结构就需要实现所有接口的成员。
using System;
interface IParentInterface
{
void ParentInterfaceMethod();
}
interface IMyInterface : IParentInterface
{
void MethodToImplement();
}
class InterfaceImplementer : IMyInterface
{
static void Main()
{
InterfaceImplementer iImp = new InterfaceImplementer();
iImp.MethodToImplement();
iImp.ParentInterfaceMethod();
}
public void MethodToImplement()
{
Console.WriteLine("MethodToImplement() called.");
}
public void ParentInterfaceMethod()
{
Console.WriteLine("ParentInterfaceMethod() called.");
}
}
十八、 命名空间
命名空间的设计目的是提供一种让一组名称与其他名称分隔开的方法,在一个命名空间中声明的类的名称与另一个命名空间中声明的相同的类的名称不冲突
18.1 定义命名空间
namespace namespace_name{}
18.2 using 关键字
using关键字表明程序使用的是给定命名空间中的名称
- using可以引入命名空间
- using static指令:指定无需指定类型名称即可访问其静态成员的类型
- 起别名
using Project = PC.MyCompany.Project
- using语句:将实例与代码绑定
using (Font font3 = new Font("Arial", 10.0f),
font4 = new Font("Arial", 10.0f))
18.3 嵌套命名空间
命名空间可以被嵌套
十九、 预处理器指令
- 预处理器指令指导编译器在实际编译开始之前对信息进行预处理
- 所有的预处理器指令都是以 # 开始。且在一行上,只有空白字符可以出现在预处理器指令之前。预处理器指令不是语句,所以它们不以分号(;)结束。
- defined 用于定义一系列称为符号的字符
- undef 用于取消定义符号
- if 用于测试符号是否为真
- else 它用于创建复合条件指令,与 #if 一起使用。
- elif 它用于创建复合条件指令。
- endif 指定一个条件指令的结束。
- line 它可以让您修改编译器的行数以及(可选地)输出错误和警告的文件名。
- error 它允许从代码的指定位置生成一个错误。
- warning 它允许从代码的指定位置生成一级警告。
- region 它可以让您在使用 Visual Studio Code Editor 的大纲特性时,指定一个可展开或折叠的代码块。
- endregion 它标识着 #region 块的结束。
二十、 异常处理
异常是在程序执行期间出现的问题
- try,标识了一个将被激活的特定的异常的代码块
- catch,程序通过异常处理程序捕获异常
- finally,用于执行给定的语句,不管异常是否被抛出都会执行
- throw,当问题出现时,程序抛出一个异常,使用throw关键字来完成
20.1 C#中的异常类
C#中的异常类主要是直接或者间接的派生于System.Exception
System.ApplicationException 和 System.SystemException 类是派生于 System.Exception 类的异常类。
System.ApplicationException 类支持由应用程序生成的异常。所以程序员定义的异常都应派生自该类。
System.SystemException 类是所有预定义的系统异常的基类。
下面是派生自System.SystemException
- System.IO.IOException 处理 I/O 错误。
- System.IndexOutOfRangeException 处理当方法指向超出范围的数组索引时生成的错误。
- System.ArrayTypeMismatchException 处理当数组类型不匹配时生成的错误。
- System.NullReferenceException 处理当依从一个空对象时生成的错误。
- System.DivideByZeroException 处理当除以零时生成的错误。
- System.InvalidCastException 处理在类型转换期间生成的错误。
- System.OutOfMemoryException 处理空闲内存不足生成的错误。
- System.StackOverflowException 处理栈溢出生成的错误。
二十一、 C#文件的输入与输出
一个文件是一个存储在磁盘中带有指定名称和目录路径的数据集合
输入流用于从文件读取数据,输出流用于向文件写入数据
21.1 C#中的I/O类
System.IO 命名空间有各种不同的类,用于执行各种文件操作,如创建和删除文件、读取或写入文件,关闭文件等。
下表列出了一些 System.IO 命名空间中常用的非抽象类:
- BinaryReader 从二进制流读取原始数据。
- BinaryWriter 以二进制格式写入原始数据。
- BufferedStream 字节流的临时存储。
- Directory 有助于操作目录结构。
- DirectoryInfo 用于对目录执行操作。
- DriveInfo 提供驱动器的信息。
- File 有助于处理文件。
- FileInfo 用于对文件执行操作。
- FileStream 用于文件中任何位置的读写。
- MemoryStream 用于随机访问存储在内存中的数据流。
- Path 对路径信息执行操作。
- StreamReader 用于从字节流中读取字符。
- StreamWriter 用于向一个流中写入字符。
- StringReader 用于读取字符串缓冲区。
- StringWriter 用于写入字符串缓冲区。
网友评论