C# 【未完成】
VIsual Studio 安装
直接下载社区版本,免费
Vlsual Studio快捷键
CLR 和 CLI
百度OK?
反编译软件
一般在C盘的 X86下面的Microsoft SDKs下面的windows Vxx 下面的bin中的 ildasm.exe
数据类型
13种基本数据类型
文档:https://learn.microsoft.com/zh-cn/dotnet/csharp/language-reference/builtin-types/built-in-types
那些有符号的都是第一位作符号位的
然后设计到钱的话,用decimal更精确
- bool表示布尔值,真或假
- char则表示一个UTF-16标准下的Unicode 字符
- char无法表示中文:中文标准是GBK、不属于UTF-16
- 中文得用string类型,emoji也可以,其实是把多个Unicode码拼接起来【String不是基本类型哦】
注意!
C 和 C++ 开发人员请注意,在 C# 中,
bool
不能转换为int
。
HElloWorld项目解刨
using System; //用 using 引入 命名空间 namespace
namespace HelloWorld //这个就是命名空间 namespace
{
class Program // 类
{
static void Main(string[] args) //主方法
{
Console.WriteLine("HelloWorld"); //语句
}
}
}
System.Console操作
- Wirte(参数)
- WirteLine(参数)
- Read()
- ReadKey()
- ReadLine()
- Clear()
String一些输出操作
@ 和 $
条件判断语句
都和Java一样
- if else
- switch
- 三元运算符 :?
循环
都和Java一样
- for
- while
- do-while
方法
方法签名
访问修饰符
声明修饰符
返回类型 和 方法名称 和 参数
方法规则:
- 静态方法只能由静态方法调用 和 Java一样
- 如果一个方法不返回任何值,那么就默认返回void
- 形参和实参 也和 Java一样,这里不讲解
- 可以用方法表达式
- 即用 => 来表示方法,代替掉了 花括号。
值传参,引用传参,输出传参
- 在参数前面加上 ref ,那么就是引用数据传递。
- 【传递变量的内存地址】
- 【注意使用和定义都要加上 ref】
- 【变量必须先定义赋值】
- 在参数前面加上 out ,那么就是输出传参。
- 【传递变量的内存地址】【注意使用和定义都要加上 out】
- 【功能和引用传参一样,但是不一样在于: 变量可以不赋值】
例:
using System;
namespace HelloWorld
{
class Program
{
public static void Swap(ref int a, ref int b)
{
a = 100;
b = 200;
}
public static void Out(out int z)
{
z = 999;
}
static void Main(string[] args)
{
int x = 1;int y = 2;
System.Console.WriteLine(x); // 1
System.Console.WriteLine(y); // 2
Swap(ref x, ref y);
System.Console.WriteLine("使用swap后:" +x); // 100
System.Console.WriteLine("使用swap后:" + y); // 200
int z; //可以不赋值
Out(out z);
Console.WriteLine(z); //999
}
}
}
面向对象
dynamic 是不确定类型数据
要 新建一个对象,直接:
dynamic obj = new {x = 15,y = 10};
其中 dynamic是不确定类型,x 和 y 相当于对象的属性,并初始了值。
创建类
public class Point{ //也是存在修饰符的 这里是public 和Java一样
public int x; //成员变量
...
//方法
public int MethodTest(int a,int b)=>System.Console.WriteLine(a);
}
创建对象
ClassName objectname = new ClassName();
public static void Main(string[] args)
{
Point point = new Point();
point.x = 123;
point.MethodTest();
}
}
public class Point //也是存在修饰符的 这里是public 和Java一样
{
public int x; //成员变量
public void MethodTest() => System.Console.WriteLine(this.x); //方法
}
构造、重载、访问修饰、封装、重写、继承
构造:
Point a = new Point {x = 1, y = 2}; //可以这样进行构造复制,这是C#独有的
//下面的是构造方法,和Java一样,其他也和Java一样
public Point()
{
this.x = 15;
y = 10;
}
重载也和Java一样
略
访问修饰
-
public 和 private 和Java一样
-
protected:只能被自己或继承自己的子类访问 也和Java一样
-
internal:访问范围:只能在同一个项目的程序集中
-
两个项目之间可以建立引用,用using进行导入
-
但是如果用了 internal 那么项目就不能被引用了。
封装可以get、set函数
独有特点:【下面相当于封装了get和set 方法,这叫“属性”】
规范:一般私有成员变量前面加个_下划线。
public class Point
{
// 成员变量x轴,使用属性
private int _x;
public int X //规范用大写
{
get { return this._x; }
set
{
if (value < 0)
{
throw new Exception("value不能小于0");
}
this._x = value;
}
}
}
-------------------------------------------------------------------------------------
//还可以:
// 成员变量Z,自动生成getter、setter
public int Z { get; set; }
//使用:
Point a = new Point(15, 10);
a.Z = 111;
Console.WriteLine(a.Z);
//使用的时候自动会给值的 非常的方便哈
point.X = 30;
Console.WriteLine(point.X);
const常量、 、只读read-only、只写write-only
只读和只写其实就是自动封装get/set的时候,如果只给一个那么就是 只读/只写
//还可以:
// 成员变量z轴,自动生成getter、setter
public int Z { get; set; }
//只读:
public int T { get; } = 123; // 123就是初始的值,如果没有定义,默认为类型的初始值
//也可以在构造函数中更改给他初始值,但是不能在普通方法中更改!
//只写:
private int _y; //如果是只写的 必须存在私有属性! 如果要读,只能在方法内部读
public int Y
{
set { _y = value; }
}
const常量:
其实就是不能修改,除了初始化,定义后就不能修改了!
readonly变量:
//readonly 变量
public readonly int b;
和const差不多,但是不同之处:
- const 定义的时候一定要初始化,否则后面就改不了【在构造也改不了!】,readonly 定义的时候可以先不赋值,构造函数或初始化赋值后, 后面就不能赋值了!
- Const在定义前就能定下来,readonly 就不是。 【const 比 readonly 性能好一点】
索引和范围
^是倒数的意思, ^1是倒数第一位
0..3 的长度就是3 ,即可: 0、1、2
索引和范围都可以进行下面操作:
Index k = ^1;
Console.WriteLine(words[k]);
Range p = 0..3;
var list = words[p];
类索引
private string[] _g = new string[]
{
// index from start index from end
"The", // 0 ^9
"quick", // 1 ^8
"brown", // 2 ^7
"fox", // 3 ^6
"jumped", // 4 ^5
"over", // 5 ^4
"the", // 6 ^3
"lazy", // 7 ^2
"dog" // 8 ^1
}; // 9 (or words.Length) ^0
public string this[int index]
{
get
{
return _g[index];
}
set
{
_g[index] = value;
}
}
// 下面是重载 根据内容查找位置 不再是int类型的 index 了
public int this[string name]
{
get
{
return Array.IndexOf(_g, name);
}
}
Partial Class局部类
注意:两个类都需要添加 partial关键字,然后两个类的名字也是一样的。里面的成员和方法也是共享的。
注意事项:
继承
C# 的继承用 :冒号来,Object是所有类的父类,然后其他和Java一样
复合 Composition
描述两个class之间的关系,不同类之间包含和被包含的关系
解决代码复用问题
完成对象间的依赖注入,适合大型项目的开发
。。。其实就是emmmm....UML的符合,设计模式。
构造方法的继承
初始化时候,基类的构造方法总是首先运行,不会被继承,在派生类中需要重新定义 【和Java一样】
但是呢,C# 是不存在super的,存在的是 :base()可以进行选择父类的构造方法
本来默认就调用父类的无参构造,现在可以用 :base() 进行选择,【Java是用super()方法】
public class Staff
{
public Staff()
{
Console.WriteLine("员工类初始化");
}
public int Number { get; set; }
public Staff(int number) //相当于用base()选择了这个构造方法
{
Number = number;
}
}
public class Manager : Staff
{
public Manager()
{
Console.WriteLine("经理类初始化");
}
public Manager(int number):base(456)
{
}
}
static void Main(string[] args)
{
var manager = new Manager(123);
Console.WriteLine(manager.Number);
}
向上转型,向下转型
其实和Java的一样。
as关键词,可以可以进行向下转型?如果失败不会抛出异常,会让对象为null。
is关键词,检查对象类型,查看是不是同一个类?
装箱boxing和拆箱
值类型、引用数据类型
保存区:栈、堆
-
值类型保存在栈 stack,例:byte/int/float/char/bool 和结构 struct
-
内存由编译器自动分配,程序结束内存会自动被回收
-
引用类型保存在堆 heap
-
程序员自己手动释放内存,Java和C#都自动垃圾回收机制
-
Class、对象一般来说都保存在 heap 中
装箱原理和Java一样,就是值类型转为引用类型的转换过程,保存的位置也是从 stack ——> heap
拆箱则相反。
装箱和拆箱都存在性能问题。
案例:
比如 array中的Add,如果加入正整数1 ,那么就是把1自动进行了装箱。
尽量避免即可。可以用泛型进行避免。
虚方法和重写
访问修饰符 virtual 函数返回类型 函数名(参数表) {函数体};
virtual关键字标记一个virtual。
修改基类的某些方法的执行逻辑
使用override关键词进行重写
其实虚方法就是类似Java中的父类中被重写的方法,Java不存在虚方法的。
C# 中虚方法被重写用 override关键字进行重写即可。
//下面就是重写了 Shape中的 虚方法 Draw()
public class Trangle : Shape
{
public override void Draw()
{
Console.WriteLine("画三角");
}
}
抽象类与抽象成员
abstract 关键字
可以修饰类、属性、方法
抽象的属性或方法是不能有代码实现的
如果有抽象成员,那么类也一定要是抽象的
如果有继承派生、那么一定要实现其中所有的抽象方法和抽象属性
抽象类不可以实例化
其实和Java也一样
sealed类与sealed成员
密封类和密封成员
sealed修饰符,可以修饰class 和 类方法
功能是防止类继承、派生类重写
所以就是如果修饰类,那么该类不能被继承
如果修饰方法,那么该方法不被重写
什么时候用?
静态类
需要存储敏感的数据
虚方法太多,重写代价过高
老师建议:十几年经验的人:重来没用过,这是个反设计模式方案?
C#中的字符串类:system.string 就是这个玩意
接口
生命和Java一样,interface关键字来修饰,.Net 规范首字母用一个I大写表示。
本文来自博客园,作者:咸瑜,转载请注明原文链接:https://www.cnblogs.com/bi-hu/p/17332907.html