文章目录
0. list方法
方法描述Clear()清除列表元素
1. StringBuilder类
- 0. list方法
- 1. StringBuilder类
- 2. 引用
- 3. LINQ查询
- 4. 新建匿名对象
- 5. c#特性
- 6. 多线程
- 7. Socket基础
- 1. tcp协议
- 2. udp协议
- 8. 通过函数名执行函数
- 9. 反射
- 10. 事件
需要引入 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
类
基本使用
static void Main(string[] args)
{
List t = new List(){
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 controlPoints = new List();
List 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
类 必须要有默认参数。
实例:
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 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 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 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 clientList = new List();
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 = "男";
// 获取该类的所有公共属性
// 如果是变量,使用 .GetFields();
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();
}