零、什么时候传参
委托,添加事件时候,线程指定方法时候,只有在运行时候才传递参数
一、正则表达式
1、定位符
2、基本元字符
3、反义字符
4、重复描述字符
string qq1 ="234234";
string qq2 = "234234234234";
sring qq3="d4234234234";
string pattern =@"^\d{5,12}$";
Console.WriteLine(Regex.IsMatch(qq1,pattern));
二、resharp
引用:106-vs插件resharper的下载安装和破解_哔哩哔哩_bilibili
作用:自动提示所用函数、类所在命名空间
三、特性与反射
引用:C#图解教程 第二十四章 反射和特性 - 只追昭熙 - 博客园 (cnblogs.com)
0、反射
*
- 程序在运行时,可以查看其他程序集或其本身的元数据。一个运行的程序査看本身的元数据或其他程序的元数据的行为叫做反射(reflection)
* 它允许程序在运行时获取关于程序集(包括类、接口、字段、属性和方法)的详细信息;并且可以在运行时候动态地创建,调用和操作对象;
* 反射使得程序可以在程序运行时通过名称来查找和调用程序集中的成员和类型,而不需要在编辑时将它们硬编码到程序中,
* 这种动态的能力可以帮助程序更加灵活地适应不同的运行环境和需求;
*
* 具体来说,使用C#反射可以实现以下功能:
* 1、动态创建对象和调用对象的方法和属性;
* 2、获取和操作数据集、类型、字段、属性、方法等成员的信息;
* 3、动态加载和卸载程序集;
* 4、实现泛型和委托的动态调用;
* 5、实现代码注入和AOP(面向切面编程)等高级编程技术;
*
* 反射功能强大,但是比较耗费资源,使用不当影响程序的性能
*
*
1、特性 Attribute
* 是一种用于为类型,成员,程序集集和其他程序元素添加元数据的语言功能;
* 特性在C#中有以下作用:
* 1、提供元数据:特性可以为程序元素添加元数据,例如类型、方法、字段等的名称、描述、版本信息,这些信息可以被编译器、开发工具和程序使用。
* 2、提供行为:特性可以为程序元素添加特定的行为,例如实现某种接口,验证数据、处理异常等,这些行为可以在程序运行时自动触发;
* 3、提供注解:特性可以为程序元素添加注解,例如标记某些代码不可用,强制编译器进行警告或错误检查等,这些注解可以帮助开发人员更好地理解和维护程序;
*
* 在C#中,特性可以通过多种方式应用到程序元素中,例如使用方括号语法应用到类型、成员或参数上,或者使用特性目标语法来指定特性的应用目标和范围,
* C#本身提供了多个内置特性,例如Serializable、Obsolete、Conditional等,同时也支持自定义特性,开发人员可以根据需要定义自己的特性来扩展程序的功能和行为。
*
*
* 特性类似于一个约束:
*
*/
四、线程与进程
multual exclusion缩写:Mutex:互斥锁
Semaphore :信号量
1、线程
异步回调:[C#][转载]BeginInvoke用法-CSDN博客
也可用lamda表达式
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
namespace P4线程与进程
{
// 1、进程
/* 一个进程包含多个线程
*
*
* 二、线程
*
* 1、多线程
*
*
*
*
*
*/
class Program
{
// 一般为比较耗时的操作,开启单独的线程执行
static int Test(int i, string s)
{
Console.WriteLine("Test");
Thread.Sleep(100);
return 100;
}
static void Main(string[] args)
{
1、通过委托开启一个线程
//Func<int, string, int> a = Test;
//IAsyncResult ar = a.BeginInvoke(100, "123", null, null); // IAsyncResult 取得当前线程的状态
// a.BeginInvoke(100,"123",null,null); // 开启一个新的线程去执行a 所引用的方法
//while(ar.IsCompleted == false)
//{
// Console.WriteLine("."); // 监测线程是否结束
//}
//int res = a.EndInvoke(ar); // 取得异步线程的返回值
//Console.WriteLine(res);
可以认为线程同时执行,,异步委托
Console.WriteLine("main");
// 2、监测线程结束
// 1000毫秒表示超时时间,如果等待了1000毫秒,线程还未结束的话,那么这个方法返回false
// 如果1000毫秒以内线程结束了,那么这个方法会返回true
//bool isEnd = ar.AsyncWaitHandle.WaitOne(1000);
//if (isEnd)
//{
// int res = a.EndInvoke(ar);
// Console.WriteLine(res);
//}
// 3、异步回调,通过回调监测西安城结束
//
Func<int, string, int> a = Test;
// 倒数第二个参数是一个委托类型的参数,表示回调函数,就是当线程结束的时候会调用这个委托指向
// 倒数第一个参数用来给回调函数传递数据
/*IAsyncResult ar = a.BeginInvoke(100, "siki", OnCallBack, a);*/ // 开启一个新的线程去执行
// lamda方法
a.BeginInvoke(100, "siki", ar =>
{
int res =a.EndInvoke(ar);
Console.WriteLine(res);
},null);
Console.ReadKey();
}
// 3、异步调用的方法,大概类似此格式
static void OnCallBack(IAsyncResult ar)
{
Func<int, string, int> a = ar.AsyncState as Func<int, string, int>;
int res = a.EndInvoke(ar);
Console.WriteLine("子线程end");
}
}
}
2、thread类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
namespace P5Thread类
{
class Program
{
static void DownloadFile(object filename)
{
Console.WriteLine("开始下载"+Thread.CurrentThread.ManagedThreadId+filename);
Thread.Sleep(2000);
Console.WriteLine("下载完成");
}
static void Main(string[] args)
{
// 1、第一种方法
Thread t = new Thread(DownloadFile); // 创建出来Thread对象,用这个线程并没有启动
t.Start("xxx.种子"); // 开始线程,,start传递参数
Console.WriteLine("Mian");
// 2、第二种lamda方法
//Thread t = new Thread(() =>
//{
// Console.WriteLine("开始下载:" + Thread.CurrentThread.ManagedThreadId);
// Thread.Sleep(2000);
// Console.WriteLine("下载完成:");
//});
//t.Start();
Console.ReadKey();
}
}
}
3、前台线程和后台线程
4、控制线程,线程的优先级
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
namespace P5Thread类
{
/*
* 1、前后台线程
*
* 只有一个前台线程在运行,应用程序的进咸亨就在运行,如果多个前台线程在运行,但是Main 方法结束了,应用程序的 进程仍然运行,知道所有的前台线程完成其任务为止
*
*
* 在默认情况下,用Thread 类创建的线程为前台线程。线程池中的线程总是后台线程
*
* 在用Thread 创建现成的时候,可以设置IsBackgroung属性, 表示它是一个前台线程还是一个后台线程
*
*
*
* 后台线程,如果关闭了Word应用程序,拼写检查继续运行就没有意义了
* 当所有前台线程运行完毕,如果还有后台线程运行的话,所有后台线程被终止
*
*
*
*
*
*
*
*
*/
class Program
{
static void DownloadFile(object filename)
{
Console.WriteLine("开始下载"+Thread.CurrentThread.ManagedThreadId+filename);
Thread.Sleep(2000);
Console.WriteLine("下载完成");
}
static void Main(string[] args)
{
// 1、第一种方法
//Thread t = new Thread(DownloadFile); // 创建出来Thread对象,用这个线程并没有启动
//t.Start("xxx.种子"); // 开始线程,,start传递参数
Console.WriteLine("Mian");
// 2、第二种lamda方法
//Thread t = new Thread(() =>
//{
// Console.WriteLine("开始下载:" + Thread.CurrentThread.ManagedThreadId);
// Thread.Sleep(2000);
// Console.WriteLine("下载完成:");
//});
//t.Start();
// 3、第三中自定义Thread
MyThread my = new MyThread("xxx.bt", "http://xxx.bbs");
Thread t = new Thread(DownloadFile);
t.IsBackground = true; // 后台线程
t.Start();
//t.Abort();
t.Join();
// 4、线程的优先级
// 当有多个线程时,,CPU根据优先级判断执行顺序,如果优先级相同,就是用一个循环调度规则,逐个执行每个线程;
// 在Thread类中,可以设置Prioty属性,一影响线程的基本优先级,Prioty属性是一个ThreadPrioty 枚举定义的一个值,
// 定义的级别有Highest/AboveNormal,BelowNormal和Lowest
// 5、控制线程
// 获取线程的状态, 但是调用了Start方法后,新线程不是马上进入Running状态,而是处于Unstarted状态;
// 只有当操作系统的线程调度器选择了要运行的线程,这个线程的状态才会修改为Running状态;
// 我们使用Thread.Sleep()方法可以让当前线程进入WaitSleepJoin状态
// 使用Thread对象的Abort()方法可以停止线程;调用这个方法,会在终止要终止的线程中抛出一个ThreadAbortException类型的异常;我们可以try catch 这个异常
// 然后再线程结束前做一些清理工作
// 如果需要等待线程的结束,可以调用Thread对象的Join方法,表示把Thread加入进来,停止当前线程,并把它设置程WaitSleepJoin状态,知道加入的线程完成为止;
Console.ReadKey();
}
}
}
5、线程池
线程池只适合做小任务,时间较短的任务,如果线程一直运行,应该用Thread创建一个线程
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
namespace P7线程池
{
/*
* 1、线程池
* 创建线程需要时间,如果有不同的小人物完成,就可以事先创建许多线程,在应完成这些任务时发出请求
* 这个线程数最好在需要更多的线程时增加,在需要释放资源时减少
* 不需要自己创建线程池,系统已经有一个ThreadPool类来管理线程。。
* 因为这个类会在需要时增加池中的线程数,直到达到最大的线程数,池中的线程数是可配置的。
* 在双核CPU中,默认为1023各工作线程和1000个I/O线程
* 也可以指定在创建线程池时应立即启动最小的线程数,以及线程池中可用的最大线程数。
* 如果有更多的作业要处理,线程池中的个数也到了极限,最新的作业就要排队,且必须等待线程完成其任务。
*
*
*
*/
class Program
{
static void ThreadMethod(object state)
{
Console.WriteLine("县城开始");
Thread.Sleep(200);
Console.WriteLine("线程结束");
}
static void Main(string[] args)
{
ThreadPool.QueueUserWorkItem(ThreadMethod); // 开启线程池
ThreadPool.QueueUserWorkItem(ThreadMethod);
Console.ReadKey();
}
}
}
6、任务
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
namespace P8线程_任务
{
class Program
{
static void ThreadMethod()
{
Console.WriteLine("县城开始");
Thread.Sleep(2000);
Console.WriteLine("线程结束");
}
static void Main(string[] args)
{
1、传递一个需要线程去执行的方法
//Task t = new Task(ThreadMethod);
//t.Start();
// 2、开始任务的第二种方法
TaskFactory tf = new TaskFactory();
tf.StartNew(ThreadMethod);
// 3、开始任务第三种
Console.ReadKey();
}
}
}
7、连接任务
8、任务层次结构
9、线程争用问题
1、线程锁加锁
2、死锁
编程开始设置锁定的顺序
五、网络编程
1、链接
六、文件IO
1、文件常规操作
class Program
{
static void Main(string[] args)
{
// 1、文件操作
//FileInfo fileinfo = new FileInfo(@"E:\实习\工作方向\TextFile1.txt"); // 相对路径
绝对路径
//FileInfo fileinfo1 = new FileInfo(@"E:\实习\工作方向\自我介绍.txt");
fileinfo1.CopyTo("tt.txt");
//Console.WriteLine(fileinfo1.Exists);
//Console.WriteLine(fileinfo1.Name); // 文件名.后缀
//Console.WriteLine(fileinfo1.Directory);
//Console.WriteLine("123");
//fileinfo.Create(); // 如果没有则创建文件
// fileinfo.MoveTo("123.txt"); // 相当于重命名操作
// 2、按照完整路径创建
DirectoryInfo dirInfo = new DirectoryInfo(@"E:\实习\工作方向\TextFile1.txt");
Console.WriteLine(dirInfo.Exists);
Console.WriteLine(dirInfo.Name);
Console.WriteLine(dirInfo.Parent);
Console.WriteLine(dirInfo.Root);
Console.WriteLine(dirInfo.CreationTime);
dirInfo.CreateSubdirectory("siki");
Console.ReadKey();
}
}
2、文件内容操作
class Program
{
static void Main(string[] args)
{
// 1、读取txt文件
string[] strArray = File.ReadAllLines(@"E:\实习\工作方向\自我介绍.txt"); // 读取文件,每一行都读取
foreach(var temp in strArray)
{
Console.WriteLine(temp);
}
2、读取图片
//byte[] data = File.ReadAllBytes(@"E:\实习\简历\公司\v2江西.jpg");
//foreach (var tp in data)
//{
// Console.Write(tp);
//}
// 3、文件写入
string[] data1 = new string[] { "123","\n", "569" };
File.WriteAllLines("E:\\实习\\工作方向\\自我介绍.txt",data1); // 字符串数组形式写入
byte[] data2 = File.ReadAllBytes(@"E:\实习\简历\公司\v2江西.jpg");
File.WriteAllBytes(@"E:\实习\简历\公司\3.png", data2); // 写入图片
Console.ReadKey();
}
}
3、FileStream读写文件
class Program
{
static void Main(string[] args)
{
// 1、创建文件流,用来操作数据
FileStream stream =new FileStream(@"E:\实习\简历\公司\3.png", FileMode.Open);
FileStream writeStream = new FileStream(@"E:\实习\简历\公司\4.png", FileMode.Create);
// 2、读取或者写入数据
byte[]data =new byte[1024];
// 3、文件过大如何,逐次读取
while (true)
{
int length = stream.Read(data, 0, data.Length);
if (length == 0)
{
Console.WriteLine("读取结束");
break;
}
else
{
writeStream.Write(data, 0, length);
}
for (int i = 0; i < length; i++)
{
Console.Write(data[i]);
}
}
// 4、文件流 完成文件复制
//FileStream readStream = new FileStream("")
// 5、创建文本文件读取流
//StreamReader reader = new StreamReader(@"E:\实习\简历\公司\3.png");
//while (true)
//{
// string str = reader.ReadLine(); // 读取一行字符串
// if (str == null)
// {
// break;
// }
// Console.WriteLine(str);
//}
//string str = reader.ReadToEnd(); // 读取到文本末
//while (true)
//{
// int str = (char)reader.Read(); // 读取一个字符,没有读到发挥-1
// if (str == -1)
// {
// break;
// }
// Console.WriteLine((char)str);
//}
// 6、文本文件写入流
StreamWriter writer = new StreamWriter(@"E:\实习\简历\公司\3.txt");
while (true)
{
string message = Console.ReadLine();
if (message == "q")
{
break;
}
writer.WriteLine(message);
}
writer.Close();
Console.ReadKey();
}
}
七、XML
1、xml文档解析
2、XML操作
1、program
class Program
{
static void Main(string[] args)
{
// 创建技能信息集合
List<Skill1> skillList = new List<Skill1>();
// 1、解析XML文档: XmlDocument
XmlDocument xmldoc = new XmlDocument();
// 选择要加载解析的xml文档的名字
//xmldoc.Load("SkillInfo.txt");
xmldoc.LoadXml(File.ReadAllText(@"E:\SoftStudy\C#\C#\网络编程\P1高级编程\_004-XML-操作\skillInfo.txt")); // 使用绝对路径
// 得到根节点
XmlNode rootNode =xmldoc.FirstChild; // 获取第一个根节点
// 得到个人呢节点下面所有子节点集合
XmlNodeList skillNodeList= rootNode.ChildNodes;
foreach(XmlNode skillNode in skillNodeList)
{
Skill1 skill = new Skill1();
XmlNodeList fileNodeList = skillNode.ChildNodes; // 获取skill接待你下面的所有节点
foreach(XmlNode filedNode in fileNodeList)
{
if (filedNode.Name == "id") // 通过Name属性,可以获取一个节点的名字
{
int id = Int32.Parse(filedNode.InnerText); // 通过获取结点内部的文本
skill.Id = id;
}
else if(filedNode.Name=="name")
{
string name = filedNode.InnerText;
skill.Name = name;
skill.Lang = filedNode.Attributes[0].Value; // 获取节点属性
}
else
{
skill.Damage = Int32.Parse(filedNode.InnerText);
}
}
skillList.Add(skill);
}
foreach(Skill1 skill in skillList)
{
Console.WriteLine(skill);
}
Console.ReadKey();
}
}
2、Skill1
class Skill1
{
/// 技能类
///
public int Id { get; set; }
public string Name { get; set; }
public string Lang { get; set; }
public int Damage { get; set; }
public override string ToString()
{
return string.Format("Id:{0},Name:{1},Lang:{2},Damage:{3}", Id, Name, Lang, Damage);
}
}
3、XML: skillInfo.txt
<skill>
<skill>
<id>2</id>
<name lang="cn">天下无双</name>
<damage>123</damage>
</skill>
<skill>
<id>3</id>
<name lang="en">tony</name>
<damage>90</damage>
</skill>
<skill>
<id>4</id>
<name lang="cn">咫尺天涯</name>
<damage>80</damage>
</skill>
</skill>
八、Json
1、介绍
官网: Json.org
Unity3D的Json篇:LitJson.dll插件_菜鸡崽子的博客-CSDN博客
1、在官网下载LitJson.dll库 ,在引用中添加LitJson.dll库
2、右键项目,在引用中打开NuGet程序包,,搜索LitJson下载
3、课程连接:
4、Json库
JavaScriptSerializer
JSON.NET
解析Json文件
生成Json文件
5、另一种教程介绍
2、LitJson
1、program
class Program
{
static void Main(string[] args)
{
// LitJson 两种下载方法
// 1、在官网下载LitJson.dll库 ,在引用中添加LitJson.dll库
// 2、右键项目,在引用中打开NuGet程序包,,搜索LitJson下载
List<Skill> skillList = new List<Skill>();
// jsonData代表一个数组或者对象
JsonData jsonData = JsonMapper.ToObject(File.ReadAllText(@"E:\SoftStudy\C#\C#\网络编程\P1高级编程\_005-Json-介绍\Json技能信息.txt"));
// 遍历
foreach(JsonData temp in jsonData)
{
Skill skill = new Skill();
JsonData idValue = temp["id"];
JsonData nameValue = temp["name"];
JsonData damageValue = temp["damage"];
int id = Int32.Parse(idValue.ToString());
int damage = Int32.Parse(damageValue.ToString());
string name = nameValue.ToString();
//Console.WriteLine("{id {0}, 上海:{1}", id,damage); // 通过键值对素偶i你
skill.id = id;
skill.name = name;
skill.damage = damage;
skillList.Add(skill);
}
foreach(Skill skill in skillList)
{
Console.WriteLine(skill);
}
Console.ReadKey();
}
}
2、Skill类
class Skill
{
public int id;
public int damage;
public string name;
public override string ToString()
{
return string.Format("Id:{0}, damage:{1},Name:{2}", id, damage, name);
}
}
3、Json技能信息.txt
[
{"id":2,"name":"天下无双","damage":123},
{"id":3,"name":"天下无","damage":13},
{"id":4,"name":"天下","damage":12}
]
3、利用泛型进行解析
1、program
4、使用泛型去解析json, json里边对象的键必须跟定义的类里边的字段或者属性保持一致
//Skill[] skillArray = JsonMapper.ToObject<Skill[]>(File.ReadAllText(@"E:\SoftStudy\C#\C#\网络编程\P1高级编程\_005-Json-介绍\Json技能信息.txt"));
//foreach (Skill skill in skillArray)
//{
// Console.WriteLine(skill);
//}
List集合形式
//List<Skill> skillArray = JsonMapper.ToObject<List<Skill>>(File.ReadAllText(@"E:\SoftStudy\C#\C#\网络编程\P1高级编程\_005-Json-介绍\Json技能信息.txt"));
//foreach (Skill skill in skillArray)
//{
// Console.WriteLine(skill);
//}
2、Skill类
参考上边8.2.2的类
3、Json技能信息.txt
参考上边8.2.3的 Json技能信息.txt
4、另一种解析方式
1、program
// 5、 利用 Player
Player p =JsonMapper.ToObject<Player>(File.ReadAllText(@"E:\SoftStudy\C#\C#\网络编程\P1高级编程\_005-Json-介绍\Json技能Player.txt"));
//Console.WriteLine(p);
foreach(var temp in p.SkillList)
{
Console.WriteLine(temp);
}
2、Player类
class Player
{
public string Name
{
get;
set;
}
public int level
{
get;
set;
}
public int age
{
get;
set;
}
public List<Skill> SkillList
{
get;
set;
}
public override string ToString()
{
return string.Format("Name:{0}, Level:{1},Age:{2},SkillList:{3}", Name, level, age, SkillList);
}
}
3、Json技能Player
{
"Name":"siki",
"Level":99,
"Age":18,
"SkillList":[
{"id":2,"name":"天下无双","damage":123},
{"id":3,"name":"天下无","damage":13},
{"id":4,"name":"天下","damage":12}
]
}
5、转换为Json对象
1、program
// 6、转换为Json文本
Player p = new Player();
p.Name = "花千骨";
p.Level = 100;
p.Age = 16;
string json = JsonMapper.ToJson(p);
Console.WriteLine(json);
2、Player类
如上 8.4.2 中的Player类