目录
一.net
组成部分 : .net平台 + .net FrameWork
二.net的编译环境VS的使用
1.解决方案,项目,类的关系:
解决方案:公司
项目:部门
类:员工
三. C#基本语法
输入:
String name=Console.readline();
输出:
Console.writeLine(name);
占位符:
C# 数据类型
在 C# 中,变量分为以下几种类型:
- 值类型(Value types)
- 引用类型(Reference types)
- 指针类型(Pointer types)
值类型:值类型变量可以直接分配给一个值。它们是从类 System.ValueType 中派生的。比如sbyte、byte、short、ushort、int、uint、long、ulong、float、double、decimal 、bool、char、枚举、自定义struct等(其中struct不能包含引用型字段)。例如当您声明一个 int 类型时,系统分配内存来存储值。
引用类型:它们指的是一个内存位置。内置的引用类型有:object、dynamic 和 string。当一个值类型转换为对象类型时,则被称为 装箱;另一方面,当一个对象类型转换为值类型时,则被称为 拆箱。
类型转换:
- 隐式转换(自动类型转换)
- 显示转换(强制类型转换)
- Convert类型转换
值传递和引用传递
- 值传递
- 引用传递:
如图这样理解
引用传递语法:
在实参和形参都加ref关键字
{
F(ref 18);
}
static int F(ref int age)
{
return age;
}
二维数组
- 二维数组和JAVA略有不同
int[,] arr=new int[3,3];
out关键字
- 作用:同时返回多个类型相同或者不相同的值
- 语法
- 注意
使用out关键字时,函数外可以不赋值,函数内必须赋值。例如上面的max和min在函数内必须要赋值,否则报错。
静态方法的调用
只能通过类名调用,不能通过对象调用,和JAVA不一样。
继承
- 特点
单继承
传递性:子类可以使用父类的父类的属性和方法。
- 用法
:
四. C#进阶
打断点:
运行后按f11
泛型
-
是什么
一个通用容器,里面可以保存任何数据,可以是Int,string等等。
形象一点比喻就是:电钻相当于这个容器,数据就是各种钻头,螺丝刀头,磨砂转盘等等。
-
怎么用
分为三种:泛型类,泛型接口,泛型函数
泛型类
namespace ConsoleApp03
{
public class TestClass<T,K>
//泛型类
{
public T value1;
public K value2;
}
class Program
{
static void Main(string[] args)
{
TestClass<int,string> tc = new TestClass<int,string>();
tc.value1 = 5;
tc.value2 = "今天好好学习";
Console.WriteLine("int输出---{0}", tc.value1);
Console.WriteLine("string输出---{0}", tc.value2);
Console.ReadKey();
}
}
}
泛型方法: 方法名<泛型占位字母>(参数列表)
注意:泛型占位字母可以有多个,用逗号分开
namespace ConsoleApp03
{
class Program
{
//泛型函数,函数返回类型也可以使用T
public static void test<T>(T value)
{
Console.WriteLine(value);
}
static void Main(string[] args)
{
test<string>("1345");
Console.ReadKey();
}
}
}
泛型类里面的泛型方法
namespace ConsoleApp03
{
class Program
{
static void Main(string[] args)
{
Test<int> t = new Test<int>();
t.Hello2<string>("qqqqq");
Test<int>.Hello(10);
Console.ReadKey();
}
}
class Test<T>
{
//这个不是泛型类里面的泛型方法,因为T是泛型类声明的时候就指定了
public static void Hello(T value)
{
}
//泛型类里面的泛型方法
public void Hello2<K>(K value)
{
Console.WriteLine(value);
}
}
}
- 不确定泛型类型的时候,想要获取这个类型的默认值,可以使用default(占位字符)。
泛型约束
-
是什么
在C#中struct(结构体类型,不能包含引用类型)是值类型,而class是引用类型。C#把基本类型规定为值类型,而把包含许多字段的较大类型规定为引用类型。
-
用法
值类型用法
-
注意
1.可以组合使用
2.可以让不同的泛型字母使用不同的约束,用where连接即可。
委托
-
是什么
委托是一种类,所有的委托(Delegate)都派生自 System.Delegate 类。可以理解成是装对应格式方法的一种容器。
-
使用场景
1. 有一天你写方法的时候想着方法能够以另一个方法作为参数。
-
声明方式
声明方式和一般的类不同。
//在命名空间里声明
访问修饰符 delegate 返回类型 委托名(参数列表);
可以声明在命名空间和class语句块中。
访问修饰符不写默认为public,在别的命名空间也可以用。
-
用法
自定义用法: 1.定义委托 2.委托实例化 3.委托赋值
namespace DelegateAppl
{
//1.定义委托
delegate int NumberChanger(int n);
class TestDelegate
{
static int num = 10;
public static int AddNum(int p)
{
num += p;
return num;
}
public static int MultNum(int q)
{
num *= q;
return num;
}
public static int getNum()
{
return num;
}
static void Main(string[] args)
{
// 2.委托实例化
NumberChanger nc1 = new NumberChanger(AddNum);
NumberChanger nc2 = new NumberChanger(MultNum);
// 3.委托赋值
nc1(25);
Console.WriteLine("Value of Num: {0}", getNum());//输出35
nc2(5);
Console.WriteLine("Value of Num: {0}", getNum());//输出175
Console.ReadKey();
}
}
}
用已定义好的委托:Func和Action。
需要引用using System;
Action:无返回值委托(参数可以根据自己情况进行传递)
namespace ConsoleApp03
{
class Program
{
static void Main(string[] args)
{
//被委托人
Action<String> action = new Action<string>(Buy);
action("爱情三十六记");
Console.WriteLine(action);
Console.ReadKey();
}
//委托人
public static void Buy(String s)
{
Console.WriteLine("买了{0} 书", s);
}
}
}
Func: 有返回值的泛型委托(参数根据自己情况情况)
namespace ConsoleApp_02
{
class Program
{
public static int Function(int i,int j,Func<int,int,int> func)
//Func<int,int,int> 前两个int和委托方法Add方法参数一样,后一个int和要委托方法Add返回类型一样
{
return func(i,j);
}
static void Main(string[] args)
{
int sum=Function(2,2,Add);
Console.WriteLine("sum====" + sum);//结果为4
Console.ReadKey();
}
public static int Add(int a,int b)
{
int sum = a + b;
return sum;
}
}
}
总结:记住无返回就用action,有返回就用Func。
-
多播委托
定义:就是一种委托类型存储多个函数(函数类型相同,实现不同)。
增:+=
减: -=
直接清空:=null
事件
Lambda表达式
-
是什么
和委托或事件配合使用
-
怎么用
有四种用法:
1. 无参无返回值
2. 有参无返回值
3. 参数类型可以省略,参数类型默认和委托或事件一致
4. 有返回值
分别对应以下代码:
- 闭包
设计模式六大原则
-
里氏替换原则
- 是什么:用父类容器装载子类对象
- 怎么用:
GameObject player=new Player();
//Player是GameObject 的一个子类
前提是要学会is和as的使用,因为使用里氏替换原则的对象不可以用.直接调用本类独有的方法。
- 作用:方便进行对象的存储和管理,特别是存储不同类对象时。例如下面这个场景。
GameObject[] objects=new GameObject[]{new Player(),new Monster(),new Boss()};
//创建一个数组里面存放不同子类的对象
for(int i=0;i<GameObject.length;i++)
{
if(GameObject[i] is Player)
{
(GameObject[i] as Player).PlayerAtk();
}
else if(GameObject[i] is Monster)
{
(GameObject[i] as Monster).MonsterAtk();
}
else if(GameObject[i] is Boss)
{
(GameObject[i] as Boss).BossAtk();
}
}
Hashtable
-
是什么
-
怎么用
1. 先引用命名空间
2. 再声明
using System.Collections;
List<int > list=new List<int>();
-
增删改查
键,值都是Object类型。
-
遍历
得到所有的键值对个数:hashtable.Count
遍历所有的键:
foreach(object item in hashtable.Keys){//注意Keys K大写
Console.WriteLine("键"+item);
Console.writeLine("值"+hashtable[item]);
}
遍历所有的值:
foreach(object item in hashtable.Values){
Console.WriteLine("键"+item);
Console.writeLine("值"+hashtable[item]);
}
迭代器遍历:
List
-
是什么
-
怎么用
1.先引用命名空间
2.再声明
using System.Collections.Generic
List<int > list=new List<int>();
-
增删改查
list.add();//加一个元素
list.AddRange(list2);//向一个list里面加list
-
遍历
长度:集合中实际元素的个数.
list.Count;
容量:集合中可包含的元素个数.
list.Capacity;
Dictionary
-
是什么
就是将hashtable的键和值类型改成自己想要的e
-
怎么用
using System.Collections.Generic
Dictionary<int,string> dictionary=new Dictionary<int,string>();
-
增删改查
查:
通过键查看值:
需要注意的地方:和hashtable不一样,通过键查看值找不到会直接报错。hashtable是会返回null,不会报错。
查看键或值是否存在:
-
遍历
遍历所有的键:
foreach(int item in dictionary.Keys){// 假设这里的键为int类型
Console.WriteLine(item);
}
遍历所有的值:
foreach(string item in dictionary.Values){// 假设这里的值为string类型
Console.WriteLine(item);
}
键值对一起遍历:
foreach(dictionary<int,string> item in dictionary){//
Console.WriteLine(item.Key+"-----"+item.Value);
}
协变和逆变
- 是什么
- 作用
只能用来修饰接口和委托中的泛型字母。用out修饰的泛型字母只能作为返回值类型,用in修饰的泛型字母只能作为参数类型。
多线程
- 是什么
- 怎么用
- 引用命名空间。
- 声明线程。
- 启动线程。
- 设置该线程为后台线程。作用:是保证进程正常被关闭。
关闭线程。如果线程不是死循环不用刻意去关闭这个线程,因为这个线程的逻辑处理完就相当于结束状态了。有死循环刻意用逻辑去关闭他,比如boolean。
using System.Threading;
namespace Console多线程
{
class Program
{
static Boolean flag = true;
static void Main(string[] args)
{
Console.WriteLine("主线程");
//什么线程,参数为一个函数
Thread thread = new Thread(NewMethod);
//线程开启
thread.Start();
//设置为后台线程
thread.IsBackground = true;
//关闭线程
flag = false;
Console.ReadKey();
}
static void NewMethod()
{
while (flag)
{
Console.WriteLine("其他线程");
}
}
}
}
- 其他方法
线程休眠:sleep(毫秒数);
- 线程之间共享数据
方法:通过lock关键字锁住代码块。
用法:
//注意多个线程想要访问同一个东西的时候,这个引用类型对象必须相同。因为系统会自动检测lock的代码块,假如一个对象正在执行,其他对象的代码块就会暂停执行。
lock(引用类型对象){
//代码逻辑
}
预处理指令
- 什么是编译器
编译器其实是一种编译程序,它将源语言程序翻译为目标语言程序。
- 预处理指令
在实际编译开始之前对信息进行预处理。
以# 开始。预处理指令不是语句,不以分号;结束。
- 常见预处理指令
1. #define #undef
2.
可以 || 或者 && 逻辑符号
3.
反射
- 什么是程序集
- 元数据
- 反射是什么
程序在运行时,查看本身或者其他程序元数据的行为就叫做反射。
- 反射的作用
程序在运行过程时,通过反射可以得到其他程序集或本身程序集代码的各种信息,如类,函数,变量,对象等等。
- 反射的用法
首先获取Type。
获取Type的方式:(三种方式)