目录
一.net
二.net的编译环境VS的使用
三. C#基本语法
输入:
输出:
占位符:
C# 数据类型
类型转换:
值传递和引用传递
二维数组
out关键字
静态方法的调用
继承
四. C#进阶
打断点:
泛型
泛型约束
委托
事件
Lambda表达式
设计模式六大原则
里氏替换原则
Hashtable
List
Dictionary
组成部分 : .net平台 + .net FrameWork
1.解决方案,项目,类的关系:
解决方案:公司
项目:部门
类:员工
String name=Console.readline();
Console.writeLine(name);
在 C# 中,变量分为以下几种类型:
值类型:值类型变量可以直接分配给一个值。它们是从类 System.ValueType 中派生的。比如sbyte、byte、short、ushort、int、uint、long、ulong、float、double、decimal 、bool、char、枚举、自定义struct等(其中struct不能包含引用型字段)。例如当您声明一个 int 类型时,系统分配内存来存储值。
引用类型:它们指的是一个内存位置。内置的引用类型有:object、dynamic 和 string。当一个值类型转换为对象类型时,则被称为 装箱;另一方面,当一个对象类型转换为值类型时,则被称为 拆箱。
如图这样理解
引用传递语法:
在实参和形参都加ref关键字
{
F(ref 18);
}
static int F(ref int age)
{
return age;
}
int[,] arr=new int[3,3];
使用out关键字时,函数外可以不赋值,函数内必须赋值。例如上面的max和min在函数内必须要赋值,否则报错。
只能通过类名调用,不能通过对象调用,和JAVA不一样。
单继承
传递性:子类可以使用父类的父类的属性和方法。
:
运行后按f11
是什么
一个通用容器,里面可以保存任何数据,可以是Int,string等等。
形象一点比喻就是:电钻相当于这个容器,数据就是各种钻头,螺丝刀头,磨砂转盘等等。
怎么用
分为三种:泛型类,泛型接口,泛型函数
泛型类
namespace ConsoleApp03
{
public class TestClass
//泛型类
{
public T value1;
public K value2;
}
class Program
{
static void Main(string[] args)
{
TestClass tc = new TestClass();
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 value)
{
Console.WriteLine(value);
}
static void Main(string[] args)
{
test("1345");
Console.ReadKey();
}
}
}
泛型类里面的泛型方法
namespace ConsoleApp03
{
class Program
{
static void Main(string[] args)
{
Test t = new Test();
t.Hello2("qqqqq");
Test.Hello(10);
Console.ReadKey();
}
}
class Test
{
//这个不是泛型类里面的泛型方法,因为T是泛型类声明的时候就指定了
public static void Hello(T value)
{
}
//泛型类里面的泛型方法
public void Hello2(K value)
{
Console.WriteLine(value);
}
}
}
是什么
在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 action = new Action(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 func)
//Func 前两个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
是什么
和委托或事件配合使用
怎么用
有四种用法:
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
是什么
怎么用
1. 先引用命名空间
2. 再声明
using System.Collections;
List list=new List();
增删改查
键,值都是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]);
}
迭代器遍历:
是什么
怎么用
1.先引用命名空间
2.再声明
using System.Collections.Generic
List list=new List();
增删改查
list.add();//加一个元素
list.AddRange(list2);//向一个list里面加list
遍历
长度:集合中实际元素的个数.
list.Count;
容量:集合中可包含的元素个数.
list.Capacity;
是什么
就是将hashtable的键和值类型改成自己想要的e
怎么用
using System.Collections.Generic
Dictionary dictionary=new Dictionary();
增删改查
查:
通过键查看值:
需要注意的地方:和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 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的方式:(三种方式)