您当前的位置: 首页 >  c#

莉萝爱萝莉

暂无认证

  • 4浏览

    0关注

    58博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

C#高级教程

莉萝爱萝莉 发布时间:2022-05-16 22:42:27 ,浏览量:4

文章目录
        • 0. list方法
        • 1. StringBuilder类
        • 2. 引用
        • 3. LINQ查询
        • 4. 新建匿名对象
        • 5. c#特性
        • 6. 多线程
        • 7. Socket基础
            • 1. tcp协议
            • 2. udp协议
        • 8. 通过函数名执行函数
        • 9. 反射
        • 10. 事件

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 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#特性
  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 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;
}
  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 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;

  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 = "男";

            // 获取该类的所有公共属性
            // 如果是变量,使用 .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();
}
关注
打赏
1663903574
查看更多评论
立即登录/注册

微信扫码登录

0.1766s