c#
using System;
namespace HelloWorldApplication
{
class HelloWorld
{
static void Main(string[] args)
{
/* 我的第一个 C# 程序*/
Console.WriteLine("Hello World");
Console.ReadKey(); /* 暂停程序,等待一个按键操作 */
Console.ReadLine() //会等待直到用户按下回车,一次读入一行
}
}
}
java标识符 是以 下划线、字母、$开头
c#标识符 是以 字母、下划线、@开头
##数据类型
类型 | 描述 | 范围 |
---|---|---|
decimal | 128 位精确的十进制值,28-29 有效位数 | (-7.9 x 1028 到 7.9 x 1028) / 100 到 28 |
sbyte | 8 位有符号整数类型 | -128 到 127 |
short | 16 位有符号整数类型 | -32,768 到 32,767 |
uint | 32 位无符号整数类型 | 0 到 4,294,967,295 |
ulong | 64 位无符号整数类型 | 0 到 18,446,744,073,709,551,615 |
ushort | 16 位无符号整数类型 | 0 到 65,535 |
float、double、long类型变量赋值添加f、d、L尾缀。默认为double类型,float不加 f 报错。
如需得到一个类型或一个变量在特定平台上的准确尺寸,可以使用 sizeof 方法。表达式 sizeof(type) 产生以字节为单位存储对象或类型的存储尺寸。
三种数据类型:值类型 ;引用类型有对象(object)类型、动态(dynamic)类型 、字符串类型;
动态类型与对象类型相似,但是对象类型变量的类型检查是在编译时发生的,而动态类型变量的类型检查是在运行时发生的。
C# string 字符串的前面可以加 @(称作"逐字字符串")将转义字符(\)当作普通字符对待
string str = @"C:\Windows"; 等价于 string str = "C:\\Windows";
@ 字符串中可以任意换行,换行符及缩进空格都计算在字符串长度之内。
System 命名空间中的 Console 类提供了一个函数 ReadLine(),用于接收来自用户的输入,并把它存储到一个变量中。
常量是使用 const 关键字来定义的 。定义一个常量的语法如下:
const <data_type> <constant_name> = value;
// ++a 先进行自增运算再赋值
##位运算符
-
异或运算(^) 也就是说,当且仅当只有一个操作数为 true 时,结果才为 true。
-
& 运算符(与) 两个操作数都为true,结果才为true
-
| 运算符(或) 只要一个操作数为true,结果就为true
-
左移 (<<)
将第一个操作数向左移动第二个操作数指定的位数,空出的位置补0。
左移相当于乘. 左移一位相当于乘2;左移两位相当于乘4;左移三位相当于乘8。 -
右移 (>>)
将第一个操作数向右移动第二个操作数所指定的位数,空出的位置补0。右移相当于整除. 右移一位相当于除以2;右移两位相当于除以4;右移三位相当于除以8。
is 判断对象是否为某一类型。 If( Ford is Car) // 检查 Ford 是否是 Car 类的一个对象。 as 强制转换,即使转换失败也不会抛出异常。 Object obj = new StringReader(“Hello”); StringReader r = obj as StringReader;
switch语句,后面跟跳转语句break或者continue 、go to xxx。最后面switch都不满足 default break 。
for循环
下面来看看它的执行过程:
1. 求解表达式1。
2. 求解表达式2。若其值为真,则执行 for 语句中指定的内嵌语句,然后执行第3步;若表达式2值为假,则结束循环,转到第5步。
3. 求解表达式3。
4. 转回上面第2步继续执行。
5. 循环结束,执行 for 语句下面的语句。
using System;
namespace zhishu;
class mathZS
{
public static void Main(string[] args)
{
int i, j;
//Boolean sign = true; 不可以放在循环外面
int count = 0;
for (i = 2; i < 100; i++)
{
Boolean sign = true;
for (j = 2; j < i; j++) {
if (i % j == 0) {
sign = false;
break;
}
}
if (sign) {
count++;
Console.WriteLine("1-100的质数为:{0}",i);
}
}
Console.WriteLine("质数有:{0}位", count);
}
}
foreach语句
int[] fibarray = new int[] { 0, 1, 1, 2, 3, 5, 8, 13 };
foreach (int element in fibarray) //element 元素
do…while 循环与 while 循环类似,但是 do…while 循环会确保至少执行一次循环。
局部变量是在函数、复合语句内、for循环中。存储在栈区;
全局变量是在函数外部定义的变量;
成员变量定义在类中,在整个类中可以被访问,成员变量随着对象的建立消失而定,存在于堆内存当中,有初始值
C# 中的 continue 语句有点像 break 语句。但它不是强迫终止,continue 会跳过当前循环中的代码,强迫开始下一次循环。
封装
封装 被定义为"把一个或多个项目封闭在一个物理的或者逻辑的包中"。在面向对象程序设计方法论中,封装是为了防止对实现细节的访问。
抽象和封装是面向对象程序设计的相关特性。抽象允许相关信息可视化,封装则使开发者实现所需级别的抽象。
一个 访问修饰符 定义了一个类成员的范围和可见性。C# 支持的访问修饰符如下所示:
- public:所有对象都可以访问;
- private:对象本身在对象内部可以访问;
- protected:只有该类对象及其子类对象可以访问
- internal:同一个程序集的对象可以访问;
- protected internal:访问限于当前程序集或派生自包含类的类型。 允许在本类,派生类或者包含该类的程序集中访问。这也被用于实现继承。
如果没有指定访问修饰符,则使用类成员的默认访问修饰符,即为 private。
方式 | 描述 |
---|---|
值参数 | 这种方式复制参数的实际值给函数的形式参数,实参和形参使用的是两个不同内存中的值。在这种情况下,当形参的值发生改变时,不会影响实参的值,从而保证了实参数据的安全。 |
引用参数 | 这种方式复制参数的内存位置的引用给形式参数。这意味着,当形参的值发生改变时,同时也改变实参的值。//使用 ref 关键字声明引用参数 /* 调用函数来交换值 */ n.swap(ref a, ref b); |
输出参数 | 这种方式可以返回多个值。 //n.getValue(out a); 使用 out 关键字声明引用参数 |
? 单问号用于对 int、double、bool 等无法直接赋值为 null 的数据类型进行 null 的赋值,意思是这个数据类型是 Nullable 类型的。
int i; //默认值0
int? ii; //默认值null 意思是这个数据类型是 Nullable 类型的
double? num3 = new double?();
double? num4 = 3.14157;
bool? boolval = new bool?();
?? 双问号用于判断一个变量在为 null 的时候返回一个指定的值。
Null 合并运算符用于定义可空类型和引用类型的默认值。Null 合并运算符为类型转换定义了一个预设值,以防可空类型的值为 Null。Null 合并运算符把操作数类型隐式转换为另一个可空(或不可空)的值类型的操作数的类型。如果第一个操作数的值为 null,则运算符返回第二个操作数的值,否则返回第一个操作数的值。
num3 = num1 ?? 5.34; // num1 如果为空值则返回 5.34
数组
数组是一个引用类型,所以您需要使用 new 关键字来创建数组的实例。
您创建一个数组时,C# 编译器会根据数组类型隐式初始化每个数组元素为一个默认值。例如,int 数组的所有元素都会被初始化为 0。
概念 | 描述 |
---|---|
多维数组 | C# 支持多维数组。多维数组最简单的形式是二维数组。 |
交错数组 | C# 支持交错数组,即数组的数组。 |
传递数组给函数 | 您可以通过指定不带索引的数组名称来给函数传递一个指向数组的指针。 |
参数数组 | 这通常用于传递未知数量的参数给函数。 |
Array 类 | 在 System 命名空间中定义,是所有数组的基类,并提供了各种用于数组的属性和方法。 |
交错数组:在声明交错数组的时候,只需要指定第一维的长度 int[ ] [ ] arr = new int [ 5 ] [ ];
参数数组:在使用数组作为形参时,C# 提供了 params 关键字,使调用数组为形参的方法时,既可以传递数组实参,也可以传递一组数组元素。params 的使用格式为: public int AddElements (params int[] arr)
ARRAY类最常用的属性 |
---|
IsFixedSize 获取一个值,该值指示数组是否带有固定大小。 |
IsReadOnly 获取一个值,该值指示数组是否只读。 |
Length 获取一个 32 位整数,该值表示所有维度的数组中的元素总数。 |
LongLength 获取一个 64 位整数,该值表示所有维度的数组中的元素总数。 |
**Rank ** 获取数组的秩(维度)。 |
序号 | ARRAY类最常用方法 & 描述 |
---|---|
1 | Clear 根据元素的类型,设置数组中某个范围的元素为零、为 false 或者为 null。 |
2 | Copy(Array, Array, Int32) 从数组的第一个元素开始复制某个范围的元素到另一个数组的第一个元素位置。长度由一个 32 位整数指定。 |
3 | CopyTo(Array, Int32) 从当前的一维数组中复制所有的元素到一个指定的一维数组的指定索引位置。索引由一个 32 位整数指定。 |
4 | GetLength 获取一个 32 位整数,该值表示指定维度的数组中的元素总数。 |
5 | GetLongLength 获取一个 64 位整数,该值表示指定维度的数组中的元素总数。 |
6 | GetLowerBound 获取数组中指定维度的下界。 |
7 | GetType 获取当前实例的类型。从对象(Object)继承。 |
8 | GetUpperBound 获取数组中指定维度的上界。 |
9 | GetValue(Int32) 获取一维数组中指定位置的值。索引由一个 32 位整数指定。 |
10 | IndexOf(Array, Object) 搜索指定的对象,返回整个一维数组中第一次出现的索引。 |
11 | Reverse(Array) 逆转整个一维数组中元素的顺序。 |
12 | SetValue(Object, Int32) 给一维数组中指定位置的元素设置值。索引由一个 32 位整数指定。 |
13 | Sort(Array) 使用数组的每个元素的 IComparable 实现来排序整个一维数组中的元素。 |
14 | ToString 返回一个表示当前对象的字符串。从对象(Object)继承。 |
//用于转化值的格式化方法
DateTime waiting = new DateTime(2012, 10, 10, 17, 58, 1);
string chat = String.Format("Message sent at {0:t} on {0:D}",
waiting);
//结果 Message: Message sent at 17:58 on Wednesday, 10 October 2012
String方法名称 & 描述 | |
---|---|
public static int Compare( string strA, string strB ) 比较两个指定的 string 对象,并返回一个表示它们在排列顺序中相对位置的整数。该方法区分大小写。 | |
public void CopyTo( int sourceIndex, char[] destination, int destinationIndex, int count ) 从 string 对象的指定位置开始复制指定数量的字符到 Unicode 字符数组中的指定位置。 | |
public bool EndsWith( string value ) 判断 string 对象的结尾是否匹配指定的字符串。 | |
public bool StartsWith( string value ) 判断字符串实例的开头是否匹配指定的字符串。 | |
public static string Format( string format, Object arg0 ) 把指定字符串中一个或多个格式项替换为指定对象的字符串表示形式。 | |
public int IndexOf( string value ) 返回指定字符串在该实例中第一次出现的索引,索引从 0 开始。 | |
public string Insert( int startIndex, string value ) 返回一个新的字符串,其中,指定的字符串被插入在当前 string 对象的指定索引位置。 | |
public static bool IsNullOrEmpty( string value ) 指示指定的字符串是否为 null 或者是否为一个空的字符串。 | |
public static string Join( string separator, string[] value, int startIndex, int count ) 连接一个字符串数组中的指定位置开始的指定元素,使用指定的分隔符分隔每个元素。 | |
public string Remove( int startIndex, int count ) 从当前字符串的指定位置开始移除指定数量的字符,并返回字符串。 | |
public string[] Split( char[] separator, int count ) 返回一个字符串数组,包含当前的 string 对象中的子字符串,子字符串是使用指定的 Unicode 字符数组中的元素进行分隔的。int 参数指定要返回的子字符串的最大数目。 | |
public string Trim() 移除当前 String 对象中的所有前导空白字符和后置空白字符。 | |
##结构
结构体是值类型数据结构。它使得一个单一变量可以存储各种数据类型的相关数据。struct 关键字用于创建结构体。
结构的特点:
- 结构可带有方法、字段、索引、属性、运算符方法和事件。
- 结构可定义构造函数,但不能定义析构函数。但是,您不能为结构定义无参构造函数。无参构造函数(默认)是自动定义的,且不能被改变。
- 与类不同,结构不能继承其他的结构或类。
- 结构不能作为其他结构或类的基础结构。
- 结构可实现一个或多个接口。
- 结构成员不能指定为 abstract、virtual 或 protected。
- 当您使用 New 操作符创建一个结构对象时,会调用适当的构造函数来创建结构。与类不同,结构可以不使用 New 操作符即可被实例化。
- 如果不使用 New 操作符,只有在所有的字段都被初始化之后,字段才被赋值,对象才被使用。
类vs结构
类和结构有以下几个基本的不同点:
- 类是引用类型,结构是值类型。
- 结构不支持继承。
- 结构不能声明默认的构造函数。
析构函数
类的 析构函数 是类的一个特殊的成员函数,当类的对象超出范围时执行。
析构函数的名称是在类的名称前加上一个波浪形(~)作为前缀,它不返回值,也不带任何参数。
析构函数用于在结束程序(比如关闭文件、释放内存等)之前释放资源。析构函数不能继承或重载。
~Line() //析构函数
{
Console.WriteLine("对象已删除");
}
static
我们可以使用 static 关键字把类成员定义为静态的。当我们声明一个类成员为静态时,意味着无论有多少个类的对象被创建,只会有一个该静态成员的副本。
关键字 static 意味着类中只有一个该成员的实例。静态变量用于定义常量,因为它们的值可以通过直接调用类而不需要创建类的实例来获取。静态变量可在成员函数或类的定义外部进行初始化。你也可以在类的定义内部初始化静态变量。
类的默认访问标识符是 internal,成员的默认访问标识符是 private。
##继承
一个类可以派生自多个类或接口,这意味着它可以从多个基类或接口继承数据和函数。
C# 中创建派生类的语法如下:
<访问修饰符> class <基类>
{
...
}
class <派生类> : <基类>
{
...
}
C# 不支持多重继承。但是,您可以使用接口来实现多重继承。
partial
Partial关键词定义的类可以在多个地方被定义,最后编译的时候会被当作一个类来处理。
多态
多态是同一个行为具有多个不同表现形式或形态的能力。
多态性意味着有多重形式。在面向对象编程范式中,多态性往往表现为"一个接口,多个功能"。
静态多态性 1.函数重载 2.运算符重载
在编译时,函数和对象的连接机制被称为早期绑定,也被称为静态绑定
**1.函数重载:**函数的定义必须彼此不同,可以是参数列表中的参数类型不同,也可以是参数个数不同。不能重载只有返回类型不同的函数声明。
2.运算符重载: 通过关键字 operator 后跟运算符的符号来定义的。
##动态多态性 抽象类
C# 允许您使用关键字 abstract 创建抽象类,用于提供接口的部分类的实现。当一个派生类继承自该抽象类时,实现即完成。抽象类包含抽象方法,抽象方法可被派生类实现。
下面是有关抽象类的一些规则:
- 您不能创建一个抽象类的实例。
- 您不能在一个抽象类外部声明一个抽象方法。
- 通过在类定义前面放置关键字 sealed,可以将类声明为密封类。当一个类被声明为 sealed 时,它不能被继承。抽象类不能被声明为 sealed。
当有一个定义在类中的函数需要在继承类中实现时,可以使用虚方法。虚方法是使用关键字 virtual 声明的。虚方法可以在不同的继承类中有不同的实现。对虚方法的调用是在运行时发生的。动态多态性是通过 抽象类 和 虚方法 实现的。
接口
接口只包含了成员的声明。成员的定义是派生类的责任。接口提供了派生类应遵循的标准结构。
接口使用 interface 关键字声明,它与类的声明类似。接口声明默认是 public 的。 通常接口命令以 I 字母开头
命名空间
为了调用支持命名空间版本的函数或变量,会把命名空间的名称置于前面,如下所示:
namespace_name.item_name;
using
using 关键字表明程序使用的是给定命名空间中的名称。
可以使用 using 命名空间指令,这样在使用的时候就不用在前面加上命名空间名称。该指令告诉编译器随后的代码使用了指定命名空间中的名称。
内嵌命名空间: 命名空间可以被嵌套,即您可以在一个命名空间内定义另一个命名空间
using语句用法: 在这个代码段中使用了using语句,它的作用是当使用SqlConnection类的实例时无论什么原因,离开这个代码段就自动调用SqlConnection类的Dispose。使用try……catch也能达到同样的目的,但是using更为方便一点。也可以这样理解:using(SqlConnection con = new SqlConnection(strCon))这句代码的意思是控制对于数据库的关闭和释放,如果是其他的内容也是同理。
在本代码中,如果using下的代码段产生错误,直接结束整段using下的代码,并且关闭数据库并释放资源。类似于try……catch,但是更为高级。因为在try……catch中如果产生某句代码产生异常,会在该句产生一个断点,中断于此并抛出异常。而且如果要释放资源,需要在catch中声明和定义。但是using会自动的释放掉这些占用的资源。
异常
C# 异常是使用类来表示的。C# 中的异常类主要是直接或间接地派生于 System.Exception 类。System.ApplicationException 和 System.SystemException 类是派生于 System.Exception 类的异常类。
System.ApplicationException 类支持由应用程序生成的异常。所以程序员定义的异常都应派生自该类。
System.SystemException 类是所有预定义的系统异常的基类。
IO
FileStream F = new FileStream("sample.txt", FileMode.Open, FileAccess.Read, FileShare.Read);
参数 | 描述 |
---|---|
FileMode | FileMode 枚举定义了各种打开文件的方法。FileMode 枚举的成员有:Append:打开一个已有的文件,并将光标放置在文件的末尾。如果文件不存在,则创建文件。Create:创建一个新的文件。如果文件已存在,则删除旧文件,然后创建新文件。CreateNew:指定操作系统应创建一个新的文件。如果文件已存在,则抛出异常。Open:打开一个已有的文件。如果文件不存在,则抛出异常。OpenOrCreate:指定操作系统应打开一个已有的文件。如果文件不存在,则用指定的名称创建一个新的文件打开。Truncate:打开一个已有的文件,文件一旦打开,就将被截断为零字节大小。然后我们可以向文件写入全新的数据,但是保留文件的初始创建日期。如果文件不存在,则抛出异常。 |
FileAccess | FileAccess 枚举的成员有:Read、ReadWrite 和 Write。 |
FileShare | FileShare 枚举的成员有:Inheritable:允许文件句柄可由子进程继承。Win32 不直接支持此功能。None:谢绝共享当前文件。文件关闭前,打开该文件的任何请求(由此进程或另一进程发出的请求)都将失败。Read:允许随后打开文件读取。如果未指定此标志,则文件关闭前,任何打开该文件以进行读取的请求(由此进程或另一进程发出的请求)都将失败。但是,即使指定了此标志,仍可能需要附加权限才能够访问该文件。ReadWrite:允许随后打开文件读取或写入。如果未指定此标志,则文件关闭前,任何打开该文件以进行读取或写入的请求(由此进程或另一进程发出)都将失败。但是,即使指定了此标志,仍可能需要附加权限才能够访问该文件。Write:允许随后打开文件写入。如果未指定此标志,则文件关闭前,任何打开该文件以进行写入的请求(由此进程或另一进过程发出的请求)都将失败。但是,即使指定了此标志,仍可能需要附加权限才能够访问该文件。Delete:允许随后删除文件。 |
属性
抽象类可拥有抽象属性,这些属性应在派生类中被实现。
public abstract string Name
{
get;
set;
}
委托
C# 中的委托(Delegate)类似于 C 或 C++ 中函数的指针。委托(Delegate) 是存有对某个方法的引用的一种引用类型变量。引用可在运行时被改变。
事件
在类的内部声明事件,首先必须声明该事件的委托类型。例如:
public delegate void BoilerLogHandler(string status);
然后,声明事件本身,使用 event 关键字:
// 基于上面的委托定义事件
public event BoilerLogHandler BoilerEventLog;
ref 和 out
可以通过值也可以通过引用传递参数。通过引用传递参数允许函数成员更改参数的值,并保持该更改。若要通过引用传递参数, 可使用ref或out关键字。ref和out这两个关键字都能够提供相似的功效,其作用也很像C中的指针变量。它们的区别是:
1、使用ref型参数时,传入的参数必须先被初始化。对out而言,必须在方法中对其完成初始化。
2、使用ref和out时,在方法的参数和执行方法时,都要加Ref或Out关键字。以满足匹配。
3、out适合用在需要retrun多个返回值的地方,而ref则用在需要被调用的方法修改调用者的引用的时候。