CLI: Common Language Infrastructure 公共语言基础框架
用来处理代码编译过程
类似Java代码编译为字节码的过程
CLR: Common Language Runtime公共语言运行时(服务环境)
代码运行环境
相当于jvm虚拟机
可以用vs自带的工具解包.exe文件
C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8 Tools idasm
类似system 等不同命名空间
直接打开.exe文件时脱离vs 需要再main()函数中添加
Console.Read();
System.Console
- IO操作工具集合(i代表input,o代表output)
Wirte(参数)、WirteLine(参数)、Read()、ReadKey()、ReadLine()、Clear
Wirte(参数)、WirteLine(参数):输出数据 后者输出时可以换行
Read()、ReadKey()、ReadLine():输入数据
-
Read() 输出数据为ASCLL代码
-
int a = Console.Read(); Console.WriteLine(a);
-
ReadLine()读取一行代码 且以字符形式展现
string b = Console.ReadLine();
Console.WriteLine(a);
- ReadKey() 获取按键比如Enter本身
ConsoleKeyInfo c = Console.ReadKey();
Console.WriteLine(c.Key);
c#基本数据类型
char 不能表示中文 要用string
内建类型,但不属于基本类型
中文得用string类型
string可以通过把多个Unicode字符拼接起来显示中文、甚至是emoji
object对象类型
dynamic动态类型
字符串操作
string有首字母大小写 但效果一样 只是通常使用string
字符串格式化处理
string name = "aaa";
int age = 12;
Console.WriteLine("My name is {0},I am {1} years old.",name,age);
string message = "My name is {0},I am {1} years old.";
string output = string.Format(message,name,age);
Console.WriteLine(output);
字符串内嵌
string message3 = $"My name is {name}. I am {age} years old.";
Console.WriteLine(message3);
原义字符
在字符串前面加@ 里面的换行等操作也会被输出
string message4 = "My name is {0}\n,I am {1}\n years old.";
string message5 = @"My name is {0}
,I am {1} years
old.";
Console.WriteLine(message4);
Console.WriteLine(message5);
面向对象
在这之前先介绍面向过程的思想
面向过程的思想
程序的运行就是一步接一步,自上而下循环运行
可以按照时间先后顺序执行方法调用,构建整个程序运行过程的代码设计方案就是典型的面向过程的编程思想
- 代码逻辑 简单粗暴 程序单线流动不需要考虑系统间的配合
- 缺点 无法处理多线程的
- 原则∶使用对象来描述世界中客观存在的一切事物
- 世界的运行过程就是不同对象互相作用的结果
- 面向对象要求我们用代码来模拟真实世界的客观运行规律
- 对象、类、实例
在面向对象的设计思路中,并不需要代码的过程,只需要定义不同的对象或不同的系统之间是如何互相影响、作用
- 从宏观上来认识、分解并且总结某个事物的运行规则 就是面向对象
对象
- 任何客观存在的事务都是对象
- 类、实例、变量、数据类型都是对象
对象的特征
- 能被执行的动作,是对象的调用方法。
- 而可以被量化的描述,则是对象的基本属性
类class
- 类面向对象息息相关
- 指 一“类”东西
- 表示一类事物的总和
- 等于是描述这一类事物的蓝图
实例instance
-
实例 表示这类事物中的某一个具体的个体
-
一般使用 new 来实例化对象
类、对象、与实例
- 每个对象都是某个类的一个实例
- 对象与实例可以划上约等号 对象≈实例
- 创建一个对象的过程就叫做实例化,而实例化的产物就叫做实例、或者叫做对象
面向对象的意义
是通过观察总结得出的定义
虽然不一定能完全符合客观规律,但它是客观事实某个片段在代码中的投影
可以在一定程度上反应客观的存在
类class与实例instance
动态数据dynamic
调用方法时可以使用
static void Main(string[] args)
{
DrawPoint(15, 15);
Console.Read();
return;
}
public static void DrawPoint(int x, int y) =>
Console.WriteLine($"左边点为 x:{x}, y:{y}");
但调用DrawPoint方法中 xy应该看做一个整体,但是是一个不确定类型 用到dynamic数据类型
static void Main(string[] args)
{
dynamic a = new { x = 15, y = 10 };
DrawPoint(a);
Console.Read();
return;
}
public static void DrawPoint(dynamic point) =>
Console.WriteLine($"左边点为 x:{x}, y:{y}");
一般来说,坐标都会使用整数或浮点数来表示 但此处方法的point并没有定义是什么类型 即使使用非数字类型的数据也不会报错 例如下面这两个
DrawPoint(new { x = "李小龙",y = "liu"});
DrawPoint(new { weather = "晴天", temperature = "-5oc" });
虽然在vs中不会报错 但在代码逻辑和业务逻辑中都彻底错误 此时运行就会出现错误
此时就轮到class 类出场
类class
此时创建一个新类 并将DrawPoint方法里的参数类型dynamic 改为Point类型
public class Point
{
public int x;
public int y;
}
public static void DrawPoint(Point point) =>
Console.WriteLine($"左边点为 x:{point.x}, y:{point.y}");
这样改完后就会发现上面那两个非法输入类型就会报错 此时需要更正代码,使用Point类型代替动态的dynamic类型
Point a = new Point();
//添加初始化数据 依然可以使用对象的链式结构访问坐标点a对象中的成员变量
a.x = 15;
a.y = 14;
更改完后 程序可以正常运行
经过class处理 完美规避了程序中可能会出现的风险,同时也对数据做出了准确的限制
但根据面向对象的原则,添加了对象、类以后也就引起了另外一个问题:对象的聚合 Cohesion
对象的聚合 Cohesion
也就是常听到的高内聚、低耦合的说法
简单来说就是功能相关的事物应该放在同一个集合中形成一个模块 这就叫做高内聚
而这些模块之间又应该是相互独立的 不同的模块之间应该保持一个低耦合的状态
从面向对象的角度来说 坐标点作为一个独立的对象与输出坐标应该是一个聚合的关系,当我们吧坐标点DrawPoint方法与坐标点Point分割的时候就违背了聚合的原则
Point a = new Point();
a.x = 15;
a.y = 14;
DrawPoint(a);
比如说 如果需求发生变化 不仅要输出坐标点,还要输出两点间的距离,就要在其他地方再加一个方法 同时需要再创建一个对象b
Point b = new Point();
b.x = 15;
b.y = 14;
GetDistances(a, b);
public static double GetDistances(Point a, Point b) =>
Math.Pow(a.x - b.x, 2) +Math.Pow(a.y - b.y, 2);
此时我们可以看出这两个方法与坐标点Point都是紧密联系的,如果将这些方法放到不同的文件中,写代码过程会非常快 但进行团队合作时代码会东一块西一块,如果有问题 补丁也是一层落一层 系统也会变的不可维护
此时就需要使用面向对象的概念来处理 将所有相关联的内容打包在一个集合中 也就是class
更改过后的代码
static void Main(string[] args)
{
Point a = new Point();
a.x = 15;
a.y = 14;
a.DrawPoint();
Point b = new Point();
b.x = 15;
b.y = 14;
a.GetDistances(b);
Console.Read();
return;
}
public class Point
{
public int x;
public int y;
public void DrawPoint() =>
Console.WriteLine($"左边点为 x:{x}, y:{y}");
public double GetDistances(Point p)=>
Math.Pow(x - p.x, 2) +Math.Pow(y - p.y, 2);
}
这时的代码依然有点繁琐 比如在实例化对象的时候并没有携带数据 数据的初始化是在下面的a.x = 设置的
使用构造函数 就可以在实例化对象的同时进行初始化