C#
基础
程序 = 数据结构 + 算法
依赖关系
1.类之间的耦合关系即为依赖
2.优秀的程序员需要做到“高内聚,低耦合”。
注释:将同功能的函数聚集到合适的类中,同类型的类聚集到合适的命名空间中。降低类与类的依赖。
3.UML(通用建模语言)类图
类是现实世界中事务抽象后得到的。
类与对象的关系
1.对象的也叫实例,是经过实例化后获得内存中的实体
2.按照类创建对象,这个就是实例化。
3.使用new关键词创建类的实例
4.类的引用
new Program();//实例化 Program program = new Program();//引用实例
类的三大成员
属性(Property)
存储数据,组合起来表示类或者对象的状态
方法(Method)
表示类能做什么。
事件(Event)
类或者对象通知其他类的一种机制,为C#所特有
关键字
保留关键字 | ||||||
---|---|---|---|---|---|---|
abstract | as | base | bool | break | byte | case |
catch | char | checked | class | const | continue | decimal |
default | delegate | do | double | else | enum | event |
explicit | extern | false | finally | fixed | float | for |
foreach | goto | if | implicit | in | in (generic modifier) | int |
interface | internal | is | lock | long | namespace | new |
null | object | operator | out | out (generic modifier) | override | params |
private | protected | public | readonly | ref | return | sbyte |
sealed | short | sizeof | stackalloc | static | string | struct |
switch | this | throw | true | try | typeof | uint |
ulong | unchecked | unsafe | ushort | using | virtual | void |
volatile | while | |||||
上下文关键字 | ||||||
add | alias | ascending | descending | dynamic | from | get |
global | group | into | join | let | orderby | partial (type) |
partial (method) | remove | select | set |
标识符
标识符是用来识别类、变量、函数或任何其它用户定义的项目。在 C# 中,类的命名必须遵循如下基本规则:
- 标识符必须以字母、下划线或 @ 开头,后面可以跟一系列的字母、数字( 0 - 9 )、下划线( _ )、@。
- 标识符中的第一个字符不能是数字。
- 标识符必须不包含任何嵌入的空格或符号,比如 ? - +! # % ^ & * ( ) [ ] { } . ; : " ’ / \。
- 标识符不能是 C# 关键字。除非它们有一个 @ 前缀。 例如,@if 是有效的标识符,但 if 不是,因为 if 是关键字。
- 标识符必须区分大小写。大写字母和小写字母被认为是不同的字母。
- 不能与C#的类库名称相同。
來自 https://www.runoob.com/csharp/csharp-basic-syntax.html
var
var 申明隐式变量
var v = "String";//隐式申明,编译器自动推断变量的数据类型,一旦确定则不能再更改。
Console.WriteLine(v.GetType().Name);
操作符
运算符就是操作符的别称
操作符是和数据类型挂钩的。
操作符是函数的“简记法”。
//new 操作符创建类的实例,并且调用其构造方法。
//如果new操作符左侧有赋值操作符的话,将会将创建的实例的内存地址交给左侧
//new 操作符还可以调用初始化器
Form form = new Form(){Text = "this is title"};
form.ShowDialog();
//new 操作符可以申明匿名对象
//var 变量名 = new {属性列表};
//new 为匿名对象创建实例,var 为隐式类型变量引用变量
var person = new { name = "张三", age = 18 };
Console.WriteLine(person.name);
Console.WriteLine(person.age);
Console.WriteLine(person.GetType().Name);
internal class Father
{
public void Report()
{
Console.WriteLine("this is Father!");
}
}
class Son:Father {
//new 关键字可以隐藏父类方法
new public void Report()
{
Console.WriteLine("this is Son!");
}
}
uint i = uint.MaxValue;
Console.WriteLine(i);
string str = Convert.ToString(i, 2);
Console.WriteLine(str);
//try{} catch(){}捕获异常,并处理
try
{
//checked 检测溢出,如果数据溢出就throw异常
//unchecked 不检测溢出
uint y = unchecked(++i);
Console.WriteLine(i);
}
catch (OverflowException e)
{
//上面如果是不检测溢出,下面就不会捕获异常
Console.WriteLine("There is Overflow!");
}
//checked 和 unchecked 可以包含代码块
//效果则是检不检测throw异常
checked
{
try
{
uint y = unchecked(++i);
Console.WriteLine(i);
}
catch (OverflowException e)
{
Console.WriteLine("There is Overflow!");
}
}
internal class Program
{
static void Main(string[] args)
{
//unsafe 不安全的,后面跟{},里面的代码块就是不安全的代码
unsafe
{
//sizeof 过去结构体存储内存的字节数
int i = sizeof(Student);
Console.WriteLine(i);
}
}
}
//struct 申明结构体
struct Student
{
int UID;
long Score;
}
internal class Program
{
static void Main(string[] args)
{
//unsafe 不安全的,后面跟{},里面的代码块就是不安全的代码
unsafe
{
Student stu;
stu.UID = 1;
stu.Score = 99;
//& 取引用,获取实例的内存地址
Student* pStu = &stu;//获取stu的内存地址
//-> 通过箭头操作指针
pStu->UID = 2;
//* 取引用,引用实例,这样就可以使用.操作符了
//需要注意的是. 操作符比* 操作符优先级高
(*pStu).Score = 100;
Console.WriteLine("Studnet UID:{0}, Score{1}",stu.UID,stu.Score);
}
}
}
//struct 申明结构体
struct Student
{
public int UID;
public long Score;
}
// is 检查变量引用的实例是否为指定类的实例,返回布尔值
Human human = new Human();
Console.WriteLine(human is Human);
// 也就是说当变量引用的为null时,则为false
Human human2 = null;
Console.WriteLine(human2 is Human);
// 当 is 指向是父类或基类也为True
Human human3 = new Human();
Console.WriteLine(human3 is Animal);
Object obj = new Human();
Console.WriteLine(obj is Human);
//当需要转化对象的类型属于转换目标类型或者转换目标类型的派生类型时,那么此转换操作才能成功,而且并不产生新的对象
//【当不成功的时候,会返回null】
object obj2 = new Human();
Console.WriteLine(obj2 as Human);
Console.WriteLine(human as Human);
Console.WriteLine(human2 as Human);
Console.WriteLine(human3 as Human);
int x = 3;
int y = 4;
double a = 20.5;
double b = 25.4;
//&& 条件与,与,并且
//&& 条件与,一方为false,则为false
if (x < y && a < b)
{
Console.WriteLine("&& 条件与,与,并且");
Console.WriteLine("&& 条件与,一方为false,则为false");
}
//|| 条件或,或者,一方为true 则为true
if (a > b || x < y)
{
Console.WriteLine("|| 条件或,或者,一方为true 则为true");
}
//&& || 条件与和或都存在短路效应,即一侧判断结果足以得出结果则不再往下执行
//如 && 左侧一开始就是false,右侧是表达式则不会执行
//|| 左侧一开始就是true,则右侧不会被执行
int i = 0;
if (true && i++ > 0)
{}
Console.WriteLine(i);
i = 0;
if (true || i++ > 0)
{ }
Console.WriteLine(i);
//Nullable<数据类型> 可空变量(泛型)
Nullable<int> i = null;
//.HasValue 获取一个Nullable<>是否有值的布尔值
Boolean b = i.HasValue;
Console.WriteLine(b);
Console.WriteLine(i == null);
//int? 等效与 Nullable<int> 一种简记法
int? j = null;
Console.WriteLine(j.HasValue);
Console.WriteLine(j.Value);//.Value 属性值
j = i ?? 59;// i ?? 59 如果i为null值将59赋值给左边,不是则将i的值赋值给左边
Console.WriteLine(j);
來自 https://www.runoob.com/csharp/csharp-operators.html
A 的值为 10,变量 B 的值为 20
术运算符
运算符 | 描述 | 实例 |
---|---|---|
+ | 把两个操作数相加 | A + B 将得到 30 |
- | 从第一个操作数中减去第二个操作数 | A - B 将得到 -10 |
* | 把两个操作数相乘 | A * B 将得到 200 |
/ | 分子除以分母 | B / A 将得到 2 |
% | 取模运算符,整除后的余数 | B % A 将得到 0 |
++ | 自增运算符,整数值增加 1 | A++ 将得到 11 |
– | 自减运算符,整数值减少 1 | A-- 将得到 9 |
关系运算符
运算符 | 描述 | 实例 |
---|---|---|
== | 检查两个操作数的值是否相等,如果相等则条件为真。 | (A == B) 不为真。 |
!= | 检查两个操作数的值是否相等,如果不相等则条件为真。 | (A != B) 为真。 |
> | 检查左操作数的值是否大于右操作数的值,如果是则条件为真。 | (A > B) 不为真。 |
< | 检查左操作数的值是否小于右操作数的值,如果是则条件为真。 | (A < B) 为真。 |
>= | 检查左操作数的值是否大于或等于右操作数的值,如果是则条件为真。 | (A >= B) 不为真。 |
<= | 检查左操作数的值是否小于或等于右操作数的值,如果是则条件为真。 | (A <= B) 为真。 |
逻辑运算符
运算符 | 描述 | 实例 |
---|---|---|
&& | 称为逻辑与运算符。如果两个操作数都非零,则条件为真。 | (A && B) 为假。 |
|| | 称为逻辑或运算符。如果两个操作数中有任意一个非零,则条件为真。 | (A || B) 为真。 |
! | 称为逻辑非运算符。用来逆转操作数的逻辑状态。如果条件为真则逻辑非运算符将使其为假。 | !(A && B) 为真。 |
位运算符
运算符 | 描述 | 实例 |
---|---|---|
& | 如果同时存在于两个操作数中,二进制 AND 运算符复制一位到结果中。 | (A & B) 将得到 12,即为 0000 1100 |
| | 如果存在于任一操作数中,二进制 OR 运算符复制一位到结果中。 | (A | B) 将得到 61,即为 0011 1101 |
^ | 如果存在于其中一个操作数中但不同时存在于两个操作数中,二进制异或运算符复制一位到结果中。 | (A ^ B) 将得到 49,即为 0011 0001 |
~ | 按位取反运算符是一元运算符,具有"翻转"位效果,即0变成1,1变成0,包括符号位。 | (~A ) 将得到 -61,即为 1100 0011,一个有符号二进制数的补码形式。 |
<< | 二进制左移运算符。左操作数的值向左移动右操作数指定的位数。 | A << 2 将得到 240,即为 1111 0000 |
>> | 二进制右移运算符。左操作数的值向右移动右操作数指定的位数。 | A >> 2 将得到 15,即为 0000 1111 |
赋值运算符
运算符 | 描述 | 实例 |
---|---|---|
= | 简单的赋值运算符,把右边操作数的值赋给左边操作数 | C = A + B 将把 A + B 的值赋给 C |
+= | 加且赋值运算符,把右边操作数加上左边操作数的结果赋值给左边操作数 | C += A 相当于 C = C + A |
-= | 减且赋值运算符,把左边操作数减去右边操作数的结果赋值给左边操作数 | C -= A 相当于 C = C - A |
*= | 乘且赋值运算符,把右边操作数乘以左边操作数的结果赋值给左边操作数 | C *= A 相当于 C = C * A |
/= | 除且赋值运算符,把左边操作数除以右边操作数的结果赋值给左边操作数 | C /= A 相当于 C = C / A |
%= | 求模且赋值运算符,求两个操作数的模赋值给左边操作数 | C %= A 相当于 C = C % A |
<<= | 左移且赋值运算符 | C <<= 2 等同于 C = C << 2 |
>>= | 右移且赋值运算符 | C >>= 2 等同于 C = C >> 2 |
&= | 按位与且赋值运算符 | C &= 2 等同于 C = C & 2 |
^= | 按位异或且赋值运算符 | C ^= 2 等同于 C = C ^ 2 |
|= | 按位或且赋值运算符 | C |= 2 等同于 C = C | 2 |
其他运算符
运算符 | 描述 | 实例 |
---|---|---|
sizeof() | 返回数据类型的大小。 | sizeof(int),将返回 4. |
typeof() | 返回 class 的类型。 | typeof(StreamReader); |
& | 返回变量的地址。 | &a; 将得到变量的实际地址。 |
* | 变量的指针。 | *a; 将指向一个变量。 |
? : | 条件表达式 | 如果条件为真 ? 则为 X : 否则为 Y |
is | 判断对象是否为某一类型。 | If( Ford is Car) // 检查 Ford 是否是 Car 类的一个对象。 |
as | 强制转换,即使转换失败也不会抛出异常。 | Object obj = new StringReader(“Hello”); StringReader r = obj as StringReader; |
优先级
类别 | 运算符 | 结合性 |
---|---|---|
后缀 | () [] -> . ++ - - | 从左到右 |
一元 | + - ! ~ ++ - - (type)* & sizeof | 从右到左 |
乘除 | * / % | 从左到右 |
加减 | + - | 从左到右 |
移位 | << >> | 从左到右 |
关系 | < <= > >= | 从左到右 |
相等 | == != | 从左到右 |
位与 AND | & | 从左到右 |
位异或 XOR | ^ | 从左到右 |
位或 OR | | | 从左到右 |
逻辑与 AND | && | 从左到右 |
逻辑或 OR | || | 从左到右 |
条件 | ?: | 从右到左 |
赋值 | = += -= *= /= %=>>= <<= &= ^= |= | 从右到左 |
逗号 | , | 从左到右 |
來自 https://www.runoob.com/csharp/csharp-operators.html
表达式
任何能得到值的运算就是表达式,C#中所有的操作符就是为了组成表达式。
internal class Program
{
static void Main(string[] args)
{
Student student = new Student();
//.成员访问操作符表达式值的类型和成员有关
Console.WriteLine(student.uid.GetType().FullName);
Console.WriteLine(student.name.GetType().FullName);
//f()方法访问操作符的表达式值的类型与方法返回值有关
Console.WriteLine(student.GetScore().GetType().FullNa
//a[x]元素访问操作符的表达式值的类型与元素有关
List<int> list = new List<int> { 1, 2, 3 };
Console.WriteLine(list[0].GetType().FullName);
double[] arr = new double[] { 1.0, 2.0, 3.0 };
Console.WriteLine(arr[0].GetType().FullName);
int i = 10;
//自增、自减 表达式的类型就是表达式值的类型
Console.WriteLine(i++.GetType().FullName);
Console.WriteLine(i--.GetType().FullName);
Console.WriteLine((++i).GetType().FullName);
Console.WriteLine((--i).GetType().FullName);
//new 操作符的表达式的值的类型就是对象的类型
Console.WriteLine(new Form().GetType().FullName);
//default 操作符的表达式的值的类型是被操作数的类型
var temp = default(Int32);
Console.WriteLine(temp.GetType().FullName);
//checked 操作符的表达式的值的类型是被操作数的类型
var x = checked(100.0+200.0);
Console.WriteLine(x.GetType().FullName);
var y = 4.0 / 3;
Console.WriteLine(y.GetType().FullName);
//?: 三元运算符表达式值的类型区精度高的
var z = 5 > 3 ? 10 : 20.0f;
Console.WriteLine(z.GetType().FullName);
}
}
class Student
{
public uint uid;
public string name;
public Student()
{
this.uid = 0;
this.name = "";
}
public int GetScore()
{
return 100;
}
}
语句
语句是高级语言的语法–编译语言和机械语言只有命令(高级语言中的表达式则对应低级语言中的指令),语句等价一个或者一组有明显逻辑关联的指令。
虽然语句是固定的,但是它可以根据输入的不同而选择分支
string str = Console.ReadLine();
double result = 0;
bool flag = double.TryParse(str,out result);//tryParse() 尝试解析
if (flag)
{
Console.WriteLine("result:"+result);
}
else
{
Console.WriteLine("not is number!");
}
C# 中语句处理顺序执行,还可以通过判断、跳转和循环来控制程序的走向。
语句的功能:陈述算法思想、控制逻辑走向,完成有意义的操作。
C#语言的语句事宜;结尾,但是以分号结尾的不一定是语句。[充分不必要]
C#语句一定是在方法体里的。