当前位置:网站首页>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. 引用

  1. Action<> 无返回值的各种引用
  2. 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#特性

  1. Obsolete
    表示一个对象已经被弃用。
// 给与提示并禁止使用该对象
[Obsolete("不要用啦", false)]
  1. 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");
        }
    }
}

  1. 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();

  1. 异步委托

无参多线程

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;
}
  1. 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("被结束的线程");
    }
}
  1. 携程
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;

  1. 首先需要明确该函数所在的类,我们可以用 type 来获得
Type t = typeof(ExcelEditor);
  1. 随后获得对应函数
MethodInfo mt = t.GetMethod("Fun");
  1. 获得函数后执行该函数
// 静态无参函数可直接执行
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();
}
原网站

版权声明
本文为[莉萝爱萝莉]所创,转载请带上原文链接,感谢
https://blog.csdn.net/qq_50682713/article/details/117409146