当前位置:网站首页>C#高级教程
C#高级教程
2022-08-02 14:11:00 【莉萝爱萝莉】
文章目录
0. list方法
方法 | 描述 |
---|---|
Clear() | 清除列表元素 |
1. StringBuilder类
需要引入 System.Text
类
高性能的字符串控制类,反复修改添加字符串时使用
// 新建一个StringBuilder类
StringBuilder sb1 = new StringBuilder("Hello World");
StringBuilder sb2 = new StringBuilder(20);
StringBuilder sb3 = new StringBuilder("Hello World", 20);
方法 | 功能 |
---|---|
Append(string) | 在尾部追加字符串 |
Insert(int, string) | 在特定位置追加字符串 |
Remove(int, int) | 在特定位置移除指定数量的字符串 |
Replace(string, string) | 搜索字符串中指定类型的字符串,将它们用另一种字符串替换 |
ToString() | 返回存储的字符串 |
2. 引用
- Action<> 无返回值的各种引用
- Func<> 有返回值的各种引用,泛形的最后一个参数为返回值类型
Delegate类
方法 | 功能 |
---|---|
GetInvocationList() | 将委托事件的所有监听转化为Delegate的列表 |
DynamicInvoke(Object[]) | 运行该监听事件 |
3. LINQ查询
需要引入 System.Linq
类
关键字 | 功能 |
---|---|
from | 被遍历对象的每一个子对象 |
in | 被遍历对象 |
where | 被遍历条件 |
select | 返回给对象的每一个子对象 |
orderby | 排序规则 |
SelectMany | 将两个对象连接 |
join in | 将两个对象连接 |
group | 查询对象某个Key出现次数 |
Any | 判断是否存在 |
All | 判断是否只有该项存在 |
基本使用
static void Main(string[] args)
{
List<Test> t = new List<Test>(){
new Test() {
id = 1, username = "liluo", password = "000" },
new Test() {
id = 2, username = "test", password = "000" },
new Test() {
id = 3, username = "qqq", password = "123123" }
};
var res1 = from m in t where true select m;
var res2 = from m in t where m.password == "000" select new Test() {
username= m.username };
foreach(var i in res1)
Console.WriteLine(i.username);
foreach (var i in res2)
Console.WriteLine(i.username);
}
class Test
{
public int id;
public string username;
public string password;
}
class Test2
{
public int id;
public int power;
}
```csharp
// 遍历列表中的每一项,然后处理数据,并将结果转化为列表
List<GameObject> controlPoints = new List<GameObject>();
List<Vector3> pointPosList = controlPoints.Select(point => point.transform.position).ToList();
其他用法
// 按照一种条件进行排序
from m in t where true orderby m.id select m;
// 按照多种条件进行排序
var res1 = t.Where((m) => {
return m.id > 0; }).OrderBy(m => m.id).ThenBy(m => m.username);
// 拼接两个类
// 连接
var res1 = t.SelectMany(m => t1, (m, k) => new {
obj1 = m, obj2 = k })
// 设置条件
.Where(x => x.obj1.id == x.obj2.id)
// 返回新对象
.Select(m => new {
id = m.obj1.id, username = m.obj1.username, password = m.obj1.password, power = m.obj2.power });
// 拼接两个类的另一种方式
var res1 = from m in t join m1 in t1 on m.id equals m1.id select new {
id = m.id, username = m.username, password = m.password, power = m1.power };
// 参数:另一个类,第一个类的哪个参数,第二个类的哪个参数,新生成的对象
var res1 = t.Join(t1, m1 => m1.id, m2 => m2.id, (m, m1) => new {
id = m.id, username = m.username, password = m.password, power = m1.power });
// 根据Key查询数量
var res1 = from m in t group m by m.username into groups select new {
data = groups.Key, count = groups.Count() };
// 拼接两个类,并根据Key查询数量
var res1 = from m in t join m1 in t1 on m.id equals m1.id into groups select new {
data = m.username, count = groups.Count() };
// 判断是否存在
var res1 = t.Any(m => m.username == "liluo");
// 判断是否只有该项存在
var res2 = t.All(m => m.username == "liluo");
4. 新建匿名对象
var d = new {
a = 3 };
5. c#特性
- Obsolete
表示一个对象已经被弃用。
// 给与提示并禁止使用该对象
[Obsolete("不要用啦", false)]
- Conditional
让一些方法只能在被定义对应宏的情况下才能被调用
需要引入System.Diagnostics
类
// 给与设定
[Conditional("start")]
宏定义:#define start
完整实例:
// 宏定义
#define start
using System;
using System.Diagnostics;
namespace Study
{
public class Program
{
public static void Main(string[] args)
{
Start();
}
[Conditional("start")]
public static void Start()
{
Console.WriteLine("Start");
}
}
}
- Caller
获得调用者的信息
需要引入System.Runtime.CompilerServices
类
必须要有默认参数。
特性类型 | 功能 |
---|---|
CallerFilePath | 调用来源文件位置 |
CallerLineNumber | 调用所在行 |
CallerMemberName | 调用函数名 |
实例:
public static void Start([CallerFilePath] string filePath = "", [CallerLineNumber]int lineNumber = 0, [CallerMemberName] string memberName = "")
{
Console.WriteLine(filePath);
Console.WriteLine(lineNumber);
Console.WriteLine(memberName);
}
6. 多线程
注意:dos运行Main结束后会直接退出程序,所以需要在Main尾部添加一个暂停。譬如:Console.ReadKey();
- 异步委托
无参多线程
public static void Main(string[] args)
{
Action a = Start;
a.BeginInvoke(null, null);
Console.WriteLine("Main");
}
public static void Start()
{
Console.WriteLine("Start");
}
带参多线程
public static void Main(string[] args)
{
Action<int, string> a = Start;
a.BeginInvoke(0, "", null, null);
Console.WriteLine("Main");
}
public static void Start(int a, string b)
{
Console.WriteLine("Start");
}
回调函数与返回值
public static void Main(string[] args)
{
Func<int, string, int> a = Start;
IAsyncResult ar = a.BeginInvoke(0, "", (c) =>
{
// 取得返回值
Console.WriteLine(a.EndInvoke(c));
}, null);
Console.WriteLine("Main");
// 判断运行是否结束
while (!ar.IsCompleted)
{
Console.Write(".");
}
Console.ReadKey();
}
public static int Start(int a, string b)
{
Console.WriteLine("Start");
// 等待10毫秒
Thread.Sleep(10);
return 0;
}
暂停程序的运行,直到异步函数返回
public static void Main(string[] args)
{
Func<int, string, int> a = Start;
IAsyncResult ar = a.BeginInvoke(0, "", (c) =>
{
// 取得返回值
Console.WriteLine(a.EndInvoke(c));
}, null);
// 暂停该程序的运行,直到异步函数返回。入参:最大等待时间
ar.AsyncWaitHandle.WaitOne(500);
Console.WriteLine("Main");
Console.ReadKey();
}
public static int Start(int a, string b)
{
Console.WriteLine("Start");
// 等待10毫秒
Thread.Sleep(10);
return 0;
}
- Thread类
基本使用
public static void Main(string[] args)
{
// 构建多线程
Thread t = new Thread(Start);
// 开启多线程,并传参
t.Start(100);
Console.WriteLine("1");
Console.ReadKey();
}
// Thread多线程,入参必须为object
public static void Start(object a)
{
Console.WriteLine("线程id:" + Thread.CurrentThread.ManagedThreadId);
Console.WriteLine("2");
// 等待10毫秒
Thread.Sleep(2000);
Console.WriteLine("3");
}
// Thread默认为前台线程,设置其为后台线程。(一旦前台线程全部运行完毕,后台线程将不再运行)
public static void Main(string[] args)
{
Thread t = new Thread(Start);
// 设置线程为后台线程
t.IsBackground = true;
t.Start();
}
public static void Start()
{
Console.WriteLine("Start");
Thread.Sleep(2000);
Console.WriteLine("End");
}
结束一个线程,并在线程中捕获这个行为
public static void Main(string[] args)
{
Thread t = new Thread(Start);
t.Start();
Thread.Sleep(1000);
// 结束线程运行
t.Abort();
}
public static void Start()
{
try
{
Console.WriteLine("Start");
Thread.Sleep(2000);
Console.WriteLine("End");
}
catch (ThreadAbortException)
{
Console.WriteLine("被结束的线程");
}
}
- 携程
IEnumerator IEnumeratorFuct()
{
// 在满足条件时不断等待(等待一帧)
while (true) yield return 1;
// 等待若干秒
yield return new WaitForSeconds(waveRate);
}
7. Socket基础
1. tcp协议
基本使用
服务器端
// 创建socket
Socket tcpServer = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
// 绑定ip、端口号
IPAddress iPAddress = IPAddress.Parse("127.0.0.1");
EndPoint point = new IPEndPoint(iPAddress, 3001);
// 申请端口号
tcpServer.Bind(point);
// 开始监听
tcpServer.Listen(100);
// 暂停当前线程,直到有客户端链接。死循环保证每个连接的用户都能连接上
while (true)
{
// 创建一个新 System.Net.Sockets.Socket 为新创建的连接。
Socket socket = tcpServer.Accept();
Client client = new Client(socket);
}
客户端
// 创建socket
Socket clientsocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
// 绑定ip、端口号
IPAddress iPAddress = IPAddress.Parse("127.0.0.1");
EndPoint point = new IPEndPoint(iPAddress, 3001);
// 连接至服务器
clientsocket.Connect(point);
客户端发送消息给服务端
// clientsocket:连接至服务器的Socket连接。
clientsocket.Send(Encoding.UTF8.GetBytes(string));
服务端端发送消息给服务端
// socket:为指定用户创建的Socket连接。
socket.Send(Encoding.UTF8.GetBytes(string));
服务端接收消息(应该启动线程处理)
byte[] getData = new byte[1024];
// socket:为指定用户创建的Socket连接。
int length = socket.Receive(getData);
string getMessage = Encoding.UTF8.GetString(getData, 0, length);
用户端接收消息(应该启动线程处理)
byte[] getData = new byte[1024];
// clientsocket:连接至服务器的Socket连接。
int length = clientsocket.Receive(data);
string message = Encoding.UTF8.GetString(data, 0, length);
用户端关闭服务
// clientsocket:连接至服务器的Socket连接。
clientsocket.Shutdown(SocketShutdown.Both);
clientsocket.Close();
Unity聊天室
服务端
using System;
using System.Threading;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Net.Sockets;
using System.Net;
using System.Text;
using System.Collections.Generic;
namespace Study
{
public class Program
{
public int a = 1;
public static List<Client> clientList = new List<Client>();
public static void Main(string[] args)
{
// 创建socket
Socket tcpServer = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
// 绑定ip、端口号
IPAddress iPAddress = IPAddress.Parse("127.0.0.1");
EndPoint point = new IPEndPoint(iPAddress, 3001);
// 申请端口号
tcpServer.Bind(point);
// 开始监听
tcpServer.Listen(100);
Console.WriteLine("服务器启动……");
// 暂停当前线程,直到有客户端链接
Socket socket;
while (true)
{
socket = tcpServer.Accept();
clientList.Add(new Client(socket));
Console.WriteLine("一个用户链接了……");
}
}
public static void BroadcastMessage(string message)
{
foreach (Client i in clientList)
{
if (i.socket.Connected)
i.SendMessage(message);
}
}
}
public class Client
{
public Socket socket;
private Thread t;
private byte[] data = new byte[1024];
public Client(Socket socket)
{
this.socket = socket;
// 启动线程处理接受
t = new Thread(ReceiveMessage);
t.Start();
}
void ReceiveMessage()
{
// 一直接受数据
while (true)
{
try
{
int length = socket.Receive(data);
string message = Encoding.UTF8.GetString(data, 0, length);
// 接受到数据的时候,把数据分发到客户端
if (socket.Poll(1000, SelectMode.SelectRead))
{
Program.clientList.Remove(this);
Console.WriteLine("一个用户断开了链接……");
break;
}
Program.BroadcastMessage(message);
Console.WriteLine("收到了消息:" + message);
}
catch
{
Program.clientList.Remove(this);
Console.WriteLine("一个用户强迫关闭了一个现有的连接……");
break;
}
}
}
public void SendMessage(string message)
{
Console.WriteLine("发送了消息");
socket.Send(Encoding.UTF8.GetBytes(message));
}
}
}
客户端(使用UGUI)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Net.Sockets;
using System.Net;
using System.Threading;
using System.Text;
public class socket : MonoBehaviour
{
public string ipaddress = "127.0.0.1";
public int port = 3001;
public UILabel label;
public Socket clientsocket;
public Thread t;
private byte[] data = new byte[1024];
void Start()
{
ConnectToServer();
}
void ConnectToServer()
{
clientsocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
// 发起请求
IPAddress iPAddress = IPAddress.Parse(ipaddress);
EndPoint point = new IPEndPoint(iPAddress, port);
clientsocket.Connect(point);
t = new Thread(ReceiveMessage);
t.Start();
}
private void Update()
{
if(dataMessage != "")
{
label.text += dataMessage;
dataMessage = "";
}
}
string dataMessage = "";
void ReceiveMessage()
{
while (true)
{
if (!clientsocket.Connected)
break;
int length = clientsocket.Receive(data);
string message = Encoding.UTF8.GetString(data, 0, length);
// 接受到数据的时候,把数据分发到客户端
Debug.Log(message);
// label.text += "\n" + message;
dataMessage = "\n" + message;
}
}
public void Send(UIInput message)
{
// Debug.Log(message);
clientsocket.Send(Encoding.UTF8.GetBytes(message.value));
message.value = "";
}
private void OnDestroy()
{
// 测试没有也行
clientsocket.Shutdown(SocketShutdown.Both);
clientsocket.Close();
}
}
使用TcpListener和TcpClient简化
服务端
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using System.Net.Sockets;
using System.Net;
namespace Study
{
class tcpListener
{
public static void Main(string[] args)
{
TcpListener listener = new TcpListener(IPAddress.Parse("127.0.0.1"), 3001);
// 开始监听
listener.Start();
int number = 0;
// 等待客户端链接
while (true)
new tcpClientList(listener.AcceptTcpClient(), number++);
// 流
// stream.Close();
// 连接
// client.Close();
// 监听
// listener.Stop();
}
class tcpClientList
{
TcpClient client;
NetworkStream stream;
int number;
byte[] data = new byte[1024];
public tcpClientList(TcpClient client, int number)
{
Console.WriteLine("新的连接:" + number,ToString());
this.number = number;
this.client = client;
stream = client.GetStream();
Thread thread = new Thread(Start);
thread.Start();
}
void Start()
{
while (true)
{
try
{
int length = stream.Read(data, 0, 1024);
string message = Encoding.UTF8.GetString(data, 0, length);
if (client.Client.Poll(1000, SelectMode.SelectRead))
{
Console.WriteLine(number.ToString() + "关闭了连接");
break;
}
Console.WriteLine("收到了" + number.ToString() + "发来的数据:" + message);
}
catch (System.IO.IOException)
{
Console.WriteLine(number.ToString() + "强行关闭了连接");
break;
}
}
}
}
}
}
客户端
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Sockets;
using System.Net;
namespace appsocket
{
class tcpclient
{
static void Main(string[] args)
{
// 创建即可连接
TcpClient client = new TcpClient("127.0.0.1", 3001);
// 流
NetworkStream stream = client.GetStream();
while (true)
{
// 读取发送数据
string message = Console.ReadLine();
byte[] data = Encoding.UTF8.GetBytes(message);
stream.Write(data, 0, data.Length);
}
// stream.Close();
// client.Close();
}
}
}
2. udp协议
服务端
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Sockets;
using System.Net;
namespace Study
{
class udp
{
public static void Main(string[] args)
{
Socket udpServer = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
// 绑定ip、端口号
IPAddress iPAddress = IPAddress.Parse("127.0.0.1");
EndPoint point = new IPEndPoint(iPAddress, 3001);
// 申请端口号
udpServer.Bind(point);
// 3.接收数据
EndPoint remoteEndPoint = new IPEndPoint(IPAddress.Any, 0);
byte[] data = new byte[1024];
while (true)
{
int length = udpServer.ReceiveFrom(data, ref remoteEndPoint);
string message = Encoding.UTF8.GetString(data, 0, length);
Console.WriteLine("从IP:" + ((IPEndPoint)remoteEndPoint).Address.ToString() + ":" + ((IPEndPoint)remoteEndPoint).Port + "收到了数据:" + message);
}
udpServer.Close();
}
}
}
用户端
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Sockets;
using System.Net;
namespace appsocket
{
class udp
{
static void Main(string[] args)
{
// 创建socket
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
EndPoint serverPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 3001);
while (true)
{
string message = Console.ReadLine();
byte[] data = Encoding.UTF8.GetBytes(message);
socket.SendTo(data, serverPoint);
}
}
}
}
使用udpClient简化
客户端
class udpClient
{
public static void Main(string[] args)
{
// 创建UdpClient
UdpClient udpClient = new UdpClient(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 3001));
while (true)
{
IPEndPoint point = new IPEndPoint(IPAddress.Any, 0);
byte[] data = udpClient.Receive(ref point);
string message = Encoding.UTF8.GetString(data);
Console.WriteLine("收到了消息:" + message);
}
}
}
用户端
class udpClient
{
public static void Main(string[] args)
{
// 创建UdpClient
UdpClient client = new UdpClient();
while (true)
{
string message = Console.ReadLine();
byte[] data = Encoding.UTF8.GetBytes(message);
client.Send(data, data.Length, new IPEndPoint(IPAddress.Parse("127.0.0.1"), 3001));
}
}
}
8. 通过函数名执行函数
using System.Reflection;
- 首先需要明确该函数所在的类,我们可以用 type 来获得
Type t = typeof(ExcelEditor);
- 随后获得对应函数
MethodInfo mt = t.GetMethod("Fun");
- 获得函数后执行该函数
// 静态无参函数可直接执行
mt.Invoke(null, null);
// 常规函数需明确其来源与参数列表
int getvalue = (int)mt.Invoke(this, new object[] {
114514 });
public int IntFun(int getvalue)
{
return getvalue;
}
using System;
using System.Collections.Generic;
using System.Reflection;
namespace test
{
public class test
{
public static void RunSchedule()
{
test type = Activator.CreateInstance(typeof(test), true) as test;
MethodInfo method = type.GetType().GetMethod("f1");
method.Invoke(type, null);
}
private void f1()
{
}
private void f2()
{
}
}
}
9. 反射
using System;
using System.Linq;
namespace CSharp反射
{
class Program
{
static void Main(string[] args)
{
Model model = new Model();
model.Name = "老王";
model.Sex = "男";
// 获取该类的所有公共属性
var props = typeof(Model).GetProperties();
// 遍历公共属性,获得在实例类 model 中,它们的值
foreach (var item in props)
{
var value = item.GetValue(model);
Console.WriteLine($"Name:{
item.Name},Value:{
value}");
// 获取指定、所有特性,以及它的值
var attr = item.GetCustomAttributes(typeof(BotAttribute), false);
if (attr.Count() > 0)
{
Console.WriteLine($"Attributes:{
((attr.ToList()[0]) as BotAttribute).IsEnable}");
}
}
Console.ReadKey();
}
}
public class Model
{
[Bot(true)]
public string Name {
get; set; }
[Bot(false)]
public string Sex {
get; set; }
}
public class BotAttribute : Attribute
{
public BotAttribute(bool isEnable)
{
IsEnable = isEnable;
}
public bool IsEnable {
get; set; }
}
}
10. 事件
event Action<> OnStart;
void Start()
{
OnStart?.Invoke();
}
边栏推荐
- Win11 keeps popping up User Account Control how to fix it
- 第二十五章:一文掌握while循环
- 第三十一章:二叉树的概念与性质
- Detailed introduction to drawing complex surfaces using the plot_surface command
- 软件测试基础知识(背)
- 轻量化AlphaPose
- Win11 system cannot find dll file how to fix
- 1.开发社区首页,注册
- LeetCode 2353. 设计食物评分系统 维护哈希表+set
- Open the door to electricity "Circuit" (3): Talk about different resistance and conductance
猜你喜欢
随机推荐
[STM32 Learning 1] Basic knowledge and concepts are clear
快速排序
测试用例练习
pygame图像连续旋转
求解斐波那契数列的若干方法
How to update Win11 sound card driver?Win11 sound card driver update method
General code for pytorch model to libtorch and onnx format
IPV4和IPV6是什么?
专硕与学硕
General syntax and usage instructions of SQL (picture and text)
MATLAB drawing command fimplicit detailed introduction to drawing implicit function graphics
IDEA 单元测试报错:Class not found
学习笔记(01):activiti6.0从入门到精通-工作流的介绍以及插件的安装
剑指offer:删除链表中重复的节点
二叉排序树与 set、map
面试汇总
mysql的索引结构为什么选用B+树?
Article pygame drag the implementation of the method
Exotic curiosity-a solution looking - bit operations
In-depth understanding of Golang's Map