学习教程:siki学院
一、字符串的使用
1,CompareTo() 方法,比较字符串的内容
string s="siki";
int res=s.CompareTo("saki"); //当两个字符串相等时,返回0,当s在字母表的排序靠前是,返回-1,反之,返回1
cosole.write(res);
2,Replace() 用另一个字符或者字符串替换字符串中给定的字符或者字符串
string s = "www.cnblogs.com/thesingel/"; //字符串类型 需要用双引号 括起来
string newStr = s.Replace(".", "/");
Console.WriteLine(s);
Console.WriteLine(newStr);
Console.ReadKey();
3.,Split() 在出现给定字符的地方,把字符串拆分称一个字符串数组
string[] strArray = s.Split('.');
foreach(var temp in strArray)
{
Console.WriteLine(temp);
}
Console.ReadKey();
4,SubString() 在字符串中检索给定位置的子字符串
string str = s.Substring(4, 11); //从开始位置的索引 截取几个字符串
Console.WriteLine(str);
5,ToLower() 把字符串转换成小写形式
string str = s.Lower();
Console.WriteLine(str);
Console.ReadKey();
6,ToUpper() 把字符串转换成大写形式
string str = s.ToUpper();
Console.WriteLine(str);
Console.ReadKey();
7,Trim 删除首尾的空白
8.Concat() 方法,合并字符串
9,CopyTo() 方法,把字符串中指定的字符复制到一个数组中
10,Format() 方法,格式化字符串
11,IndexOf() 方法,取得字符串第一次出现某个给定字符串或者字符的位置
12,IndexOfAny() 方法
13,Insert() 把一个字符串实例插八到另一个字符串实例的制定索引处
14,Join()合并字符串数组,创建一个新字符串
二、StringBuild类
1.定义的三种形式
//1
//StringBuilder s = new StringBuilder("www.cnblogs.com/thesingel");//string 是不可变的 而stringbuild的内容时可变的,输入的字符串为初始长度
//2
//StringBuilder s = new StringBuilder(20);//定义初始是的长度为20 当修改时 内存不够 则会申请内存变为2倍
//3
StringBuilder s = new StringBuilder("www.cnblogs.com/thesingel", 100);//定义了初始字符串 以及初始申请的内存长度为100
2.string和StringBuild的区别
StringBuilder str = new StringBuilder("www.cnblogs.com/thesingel", 100);//定义了初始字符串 以及初始申请的内存长度为100
str.Append("/thesingel");
Console.WriteLine(str);
string s = "www.cnblogs.com";
s = s + "/thesingel";
Console.WriteLine(s);
Console.ReadKey();
//当频繁对字符进行添加删减时,使用StringBuild的效率会更高一些
3.StringBuild的更多方法
三、正则表达式
1. 正则表达式是由普通字符以及特殊字符(成为元字符)组成的文字模式
2.静态方法Match
检索匹配
3.定位元字符
^ 定位字符串的开始位置
string s="I am a cat";
string res = Regex.Replace(s,"^","开始:");//搜索字符串符合正则表达式的情况,然后把所有符合的位置进行替换成后面的字符串
$ 定义字符串的结束位置
string res=Regex.Replace(s,"$","结束");
4.基本语法元字符
isMatch
string pattern = @"^\d*$"//正则表达式
^\d 表示以数字开头 加上* 表示有0个或者多个\d的数字字符 加上$表示以数字结尾 @表示\d不是转义字符 而是正则表达式的意思
5.反义字符
[abc] 匹配中括号之内的所有字符
[^x] 匹配除了X以外的任意字符
string str = "I am a cat"
string pattern = @"[^ahou]";// 它代表一个字符 表示除了ahou的任意一个字符
string s=Regex.Repalce(str,pattren,"*"); //将str字符串中的字符替换成* ,但是ahou这几个字符不进行替换
6.重复描述字符
{n,m} 重复字符n到m次
7.择一匹配
| 逻辑或运算
@"[;,.]"==@"[;]|[,]|[.]"
[]中的满足其中一个即可
8.正则表达式的分组
分组操作符()
ip地址的正则表达式形式
@"(((2[0-4]\d|25[0-5][01]?\d\d?)\.){3}(2[0-4]\d|25[0-5][01]?\d\d?))$"
四、委托
1.关键字 delegate
2.把委托类型当做参数来使用
3.Action委托
action是系统内置(预定义)的一个委托类型,它可以指向一个没有返回值,没有参数的方法
Action<int> a ;//定义了一个委托类型,这个类型可以指向一个没有返回值,有一个int参数的方法
Action<type,tepe....> actionName 其中里面的类型可以放0~16个
4.Func委托
必须有一个返回值
Func<string,int> a=Test1;// Func的泛型类型 前面的指的是参数类型,后面的int指的是返回值类型
参数类型必须给指向的方法的类型的参数类型按照顺序对应
五、冒泡排序
1.int 简单冒泡排序
namespace 冒泡排序法
{
class Program
{
static void sortAarry(int[] array)
{
bool swap = true;
do
{
swap = false;
for (int i = 0; i < array.Length - 1; i++)
{
if (array[i] > array[i + 1])
{
int temp = array[i];
array[i] = array[i + 1];
array[i + 1] = temp;
swap = true;
}
}
} while (swap);
}
static void Main(string[] args)
{
int[] sortarray = new int[] { 1, 2, 45, 78, 44, 23, 54 };
sortAarry(sortarray);
foreach (var temp in sortarray )
{
Console.Write(temp+" ");
}
Console.ReadKey();
}
}
}
2.冒泡排序的拓展
六、多播委托
多播委托调用多个方法时 返回值是最后一个方法的返回值类型 所以一般声明为void 无返回值类型
class Program
{
static void Test1()
{
Console.WriteLine("test1");
}
static void Test2()
{
Console.WriteLine("test2");
}
static void Main(string[] args)
{
//多播委托
Action a = Test1;
//a = Test2; 此时a 指向的是Test2 而Test1的指向已经被覆盖掉了 所以不属于多播委托
// 多播委托 表示既可以指向Test1 又可以指向Test2
a += Test2;//表示添加了 一个委托Test2
a -= Test1;//表示去掉了a中的Test1委托 只保留了Test2委托
a -= Test2;
//当一个委托没有调用任何一个方法的时候 会出现异常,
// 在执行委托时 要判断委托是否为空 如果委托不为空的时候 即可进行调用
if(a!=null)
a();
Console.ReadKey();
}
}
七、匿名方法
class Program
{
static int Test1(int arg1,int arg2)
{
return arg1 + arg2;
}
static void Main(string[] args)
{
//Func<int, int, int> puls = Test1;
//修改成匿名方法的形式
//delegate 是匿名方法的关键字
Func<int, int, int> puls = delegate (int arg1, int arg2)
{
return arg1 + arg2;
};
//匿名方法本质上是一个方法,只是没有名字,任何使用委托变量的地方都可以是使用匿名方法赋值
Console.ReadKey();
}
}
八、Lambda表达式
class Program
{
static void Main(string[] args)
{
//lambda表达式 用来代替匿名方法 所以一个lambda表达式 也是定义了一个方法
//Func<int, int, int> puls = delegate (int arg1, int arg2)
//{
// return arg1 + arg2;
//};
//lambda 表达式不需要在声明delegate关键字 ,并且lambda表达式的参数不需要声明类型
Func<int, int, int> puls = (arg1, arg2) =>
{
return arg1 + arg2;
};
Console.WriteLine(puls(90,60));
Console.ReadKey();
}
}
九、事件
十、观察者模式(猫捉老鼠)
十一、数据的初始化和LINQ总结
var res = from m in masterList //from后面表示查询的集合,m是为这个查询到的内容定义一个别名,而in后面的则是查询的集合
where m.Level > 8 //where后面表示 查询的条件
select m; //表示返回m 武林高手类型集合 或者m.Level 只返回其中的等级
1.拓展方法
var res = masterList.Where(Test1);
//过滤方法
static bool Test1(MartialArtsMaster master)
{
if (master.Level > 8) return true;
else return false;
}
2.拓展方法
//获得所学功夫的杀伤力为100的大侠
var res = from m in masterList
from k in kongfuList
where m.Kongfu == k.KongfuName && k.Lethality == 100
//select new {master = m, kongfu = k};
select m;
3.查询结果进行倒叙排列时
//对查询的结果做排序 orderby(descending)
var res = from m in masterList
from k in kongfuList
where m.Kongfu == k.KongfuName && k.Lethality == 100
//select new {master = m, kongfu = k};
//进行倒序排序时 在需要倒序排序的字段后 加上关键字 descending
orderby m.Age descending ,m.Level descending //先按照第一个属性排序 如果字段相同 则按照第二个字段排序
select m;
Oderby Thenby
4.联合查询 join on
var res = from m in masterList
join k in kongfuList on m.Kongfu equals k.KongfuName
where m.Level>8
select m;
5.into groups 分组查询
6.按字段分组 group
//按照字段进行分组 group
var res = from m in masterList
group m by m.Menpai
into g
select new {count = g.Count(), key = g.Key};// key 代表按照那个属性分的组
7.量词操作符 any all
bool res =masterList.Any(m => m.Menpai == "丐帮");
Console.Write(res);
bool res =masterList.All(m => m.Menpai == "丐帮");
Console.Write(res);
第十二 反射和特性
1.type类
2.Assembly 程序集
MyCalss my = new MyCalss();
Assembly assembly = my.GetType().Assembly;
Console.WriteLine(assembly.FullName);
Type[] types = assembly.GetTypes();
foreach (var type in types)
{
Console.Write(type);
}
Console.ReadKey();
3.obsolete 特性
[Obsolete("这个方法被弃用了,请使用NewMenther来代替",true)]
static void OldMenther()
{
Console.WriteLine("OldMenther");
}
static void NewMenther()
{
Console.WriteLine("这是新的方法!");
}
static void Main(string[] args)
{
OldMenther();
Console.ReadKey();
}
4.conditional 特性
#define IsTest //定义一个宏
[Conditional("IsTest")] //当IsTest被定义时 test1()会被编译 反之,则不会编译,但是test1()中的方法 则还是会被储存下来
static void test1()
{
Console.WriteLine("test1");
}
static void test2()
{
Console.WriteLine("test2");
}
static void Main(string[] args)
{
test1();
test2();
test1();
Console.ReadKey();
}
5.调用者信息特性
6.DebuggerStepThrough 特性
可以跳过单个debug的测试步骤
7.创建自定义特性
第十三 线程和进程
1.异步委托
beginInvoke 开启新的线程
2.检测委托线程的结束——通过等待句柄和回调函数
3.线程的开启—Thread类
static void DownLoad()
{
Console.WriteLine("starting download!");
Thread.Sleep(2000);
Console.WriteLine("finished download!");
}
static void Main(string[] args)
{
Thread t = new Thread(DownLoad);
t.Start();
Console.WriteLine("main");
Console.ReadKey();
}
4.线程的其他概念 前台线程 后台线程 线程的优先级 线程的状态
vs 默认会创建前台线程 当前台线程结束之后 后台线程会被强制结束
xiancheng.IsBackground =true 则会被判断为后台线程
5.线程的开启——线程池
namespace _11_线程池
{
//线程池 中的线程都是 后台线程
class Program
{
static void ThreadMethod(object state)
{
Console.WriteLine("开始线程:"+Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(2000);
Console.WriteLine("结束线程");
}
static void Main(string[] args)
{
ThreadPool.QueueUserWorkItem(ThreadMethod); //调用时 必须跟一个参数
ThreadPool.QueueUserWorkItem(ThreadMethod); //开启一个工作线程
ThreadPool.QueueUserWorkItem(ThreadMethod);
ThreadPool.QueueUserWorkItem(ThreadMethod);
ThreadPool.QueueUserWorkItem(ThreadMethod);
ThreadPool.QueueUserWorkItem(ThreadMethod);
Console.ReadKey();
}
}
}
6.线程的开启——任务
7.连续任务
continueWith
8.线程问题——争用条件和死锁
当两个线程执行同一个条件时,由于执行的速度不同,可能会出现 逻辑上我们不想得到的效果 因此我们可以利用锁的情况 来设定先后执行的 顺序 (数据结构复习。。。)
死锁情况: 当两个线程执行中,相互用到了其中的条件, 但是两者各自锁定,造成死锁,从而无法进行条件的执行
第十四 socket编程——tcp协议
1.服务器端
// 1.创建socket
Socket tcpSever = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//2.绑定ip和端口号
IPAddress ipaddress = new IPAddress(new byte[] {192,168 ,42 ,73});
EndPoint point = new IPEndPoint(ipaddress, 7788);//ipendpoint是对ip+端口做了一层封装的类
tcpSever.Bind(point);//向操作系统申请一个可用的ip和端口号 用来做通信
//3.开始监听 (等待客户端连接)
tcpSever.Listen(100);//参数是最大连接数
Console.WriteLine("开始监听");
Socket clientSocket = tcpSever.Accept();//暂停当前线程,直到有一个客户端连接过来,之后进行下面的代码
//使用返回的socket和客户端做通信
Console.WriteLine("一个客户端连接过来了");
string message = "hello 欢迎你";
byte[] date = Encoding.UTF8.GetBytes(message);//对字符串做编码,得到一个字符串的字节数组
clientSocket.Send(date);
Console.WriteLine("客户端发送过来了一条消息");
byte[] date2 = new byte[1024]; //创建一个字节数组作为容器 来承接客户端发过来的数据
int length = clientSocket.Receive(date2);
string message2 = Encoding.UTF8.GetString(date2, 0, length);
Console.WriteLine("接收到了一条从客户端发过来的消息"+message2);
Console.ReadKey();
2.客户端
//1,创建socket
Socket tcpClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//2,发起建立连接的请求
IPAddress ipaddress = IPAddress.Parse("192.168.42.73");
EndPoint point = new IPEndPoint(ipaddress, 7788);
tcpClient.Connect(point);//通过ip:端口号 定位一个要连接到的服务器端
byte[] date = new byte[1024];
int length = tcpClient.Receive(date);//这里传递一个byte数组 实际上这个date数组用来接受数据
//length 返回值表示接收了多少字节的数据
string message = Encoding.UTF8.GetString(date, 0, length);//只把接受到的数据做一个转化
Console.WriteLine(message);
//向服务器端 发送一条消息
string message2 = Console.ReadLine();//读取用户的输入 并且发送到服务器端
tcpClient.Send(Encoding.UTF8.GetBytes(message2));//把字符串转化为byte数组
Console.ReadKey();
第十四 socket编程——UDP协议
1.服务器端
//1.创建socket
Socket udpSever = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
//2.绑定ip和端口号
udpSever.Bind(new IPEndPoint(IPAddress.Parse("192.168.42.73"),7788));
//3.接受数据
EndPoint remoteEndPoint = new IPEndPoint(IPAddress.Any, 0);
byte[] date = new byte[1024];
int length = udpSever.ReceiveFrom(date, ref remoteEndPoint);//这个方法会把数据的来源(ip:prot)放到第二个参数上
string message = Encoding.UTF8.GetString(date, 0, length);
Console.WriteLine("从ip:"+(remoteEndPoint as IPEndPoint).Address.ToString()+":"+(remoteEndPoint as IPEndPoint).Port+"收到了数据:"+message);
2.客户端
//1. 创建socket
Socket udpClient = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
//发送数据
EndPoint severPoint = new IPEndPoint(IPAddress.Parse("192.168.42.73"), 7788);
string message = Console.ReadLine();
byte[] date = Encoding.UTF8.GetBytes(message);
udpClient.SendTo(date, severPoint);
Console.ReadKey();
第十五 socket编程 tcp协议和udp协议的区别
1.socket-tcpclient tcplistenter
第十六 文件操作
1.文件的操作
//1 相对路径:就是寻找当前程序运行的所在路径
FileInfo fileInfo = new FileInfo("TextFile1.txt");
Console.WriteLine(fileInfo.Exists);
Console.ReadKey();
//2 绝对路径: 加上完整的路径名
FileInfo fileInfo = new FileInfo(@"C:\Users\DMT01\Documents\Visual Studio 2017\Projects\CSharp高级教程\17 文件操作\TextFile1.txt");
Console.WriteLine(fileInfo.Exists);
Console.ReadKey();
2.文件夹的操作
DirectoryInfo
3.使用file读写文件
4.创建FileStream文件流
比较适合读取二进制文件,例如png图片等;
5.使用StreamReader和streamwriter 读写文本
StreamReader streamReader = new StreamReader("TextFile1.txt");
while (true)
{
string str = streamReader.ReadLine();
if(str==null) break;
Console.WriteLine(str);
}
Console.ReadKey();
第十七 xml文档
1.xml文档
拥有特定结构的标记语言 树形结构
2.xml的语法规则
文档必须有根元素 属性值必须加引号
第十八 json介绍
1.json的操作
2.json的语法规则
键值对 {“LastName”:“Siki”}
3.json的数据结构
4.引入LitJson的两种方式
(1) 官网引入 json.org
(2)vs——拓展与更新——联机——搜素下载
第十九 插件resharper的配置使用
1.resharper快捷键使用 选择第二个 IDEA
.