c#模仿内置 Socket.Receive(无需 out/ref,直接写回数据)

、正确实现:模仿内置 Socket.Receive(无需 out/ref,直接写回数据)

核心:去掉 out/ref,利用数组「引用类型」的特性,直接修改数组内容(和内置 Socket 逻辑一致),调用时无需加任何关键字:

cs 复制代码
public class Newsocket
{
    // 模拟内置 Socket 的 Receive 逻辑(无 out/ref,数组默认按引用传递)
    public int Receive(byte[] buffer)
    {
        // 1. 校验参数(和内置 Socket 保持一致)
        if (buffer == null)
            throw new ArgumentNullException(nameof(buffer));
        if (buffer.Length == 0)
            throw new ArgumentException("缓冲区长度不能为0", nameof(buffer));

        try
        {
            // 2. 模拟接收数据(替换为你的实际逻辑:如从 Tool2 取数据/原生 Socket 接收)
            // 示例:模拟接收到 10 字节数据,写入调用方的 buffer
            byte[] receivedData = new byte[] { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A };
            
            // 3. 核心:将数据写入调用方的 buffer(数组是引用类型,直接修改内容)
            int copyLength = Math.Min(receivedData.Length, buffer.Length); // 避免越界
            Array.Copy(receivedData, 0, buffer, 0, copyLength);
            
            // 4. 多余位置置0(可选,和内置 Socket 行为一致)
            if (copyLength < buffer.Length)
                Array.Clear(buffer, copyLength, buffer.Length - copyLength);

            // 5. 返回实际接收的字节数(和内置 Socket 保持一致)
            return copyLength;
        }
        catch (Exception ex)
        {
            Console.WriteLine($"接收异常:{ex.Message}");
            return -1; // 异常返回-1,内置 Socket 会抛异常,你可按需调整
        }
    }
}

// 你的静态类(无变化)
public static class chuankou
{
    public static Newsocket socket = new Newsocket();
}
调用(和内置 Socket 完全一致,无需任何关键字)

csharp

运行

复制代码
// 和调用内置 Socket.Receive 一模一样,无任何关键字,无 CS1620 错误
byte[] readBuffer3 = new byte[53];
int recvLength = chuankou.socket.Receive(readBuffer3);

// 处理结果:recvLength 是实际接收的字节数,readBuffer3 前 recvLength 字节是有效数据
if (recvLength > 0)
{
    Console.WriteLine($"接收 {recvLength} 字节,数据:{BitConverter.ToString(readBuffer3, 0, recvLength)}");
}

三、核心原理:数组的 "值传递" vs "引用传递"

很多人误以为 out/ref 是修改数组的唯一方式,其实是对 C# 类型的误解:

类型 参数传递方式 能否修改内容 能否修改引用 调用是否需关键字
引用类型(数组 / 对象) 普通值传递(无修饰) ✅ 可以(如修改 buffer [0]) ❌ 不可以(如 buffer = new byte [10]) ❌ 无需
任意类型 ref 修饰 ✅ 可以 ✅ 可以 ✅ 需加 ref
任意类型 out 修饰 ✅ 可以 ✅ 可以 ✅ 需加 out
  • 内置 Socket.Receive 只需要修改数组内容 ,因此用「普通值传递」即可,无需 out/ref
  • 你之前错误地用了 out/ref,是 "过度设计",导致调用时必须加关键字。

总结

  1. 错误根源 :你的 Receive 方法加了 out/ref 修饰,而内置 Socket.Receive 无任何修饰;
  2. 核心修正 :去掉 out/ref,利用数组「引用类型」特性直接修改内容(和内置 Socket 逻辑一致);
  3. 调用体验 :修改后 chuankou.socket.Receive(readBuffer3) 无需任何关键字,和调用内置 Socket 完全一样,彻底消除 CS1620 错误;
  4. 关键规则 :仅当需要修改「变量的引用」(如 buffer = new byte[10])时,才需要 out/ref;仅修改数组内容,无需加任何修饰。

按上述代码实现后,你的 Receive 方法会和内置 Socket.Receive 行为完全一致,调用简洁且无语法错误。

相关推荐
方安乐4 小时前
python之向量、向量和、向量点积
开发语言·python·numpy
小小小米粒5 小时前
Collection单列集合、Map(Key - Value)双列集合,多继承实现。
java·开发语言·windows
czhc11400756636 小时前
C# 428 线程、异步
开发语言·c#
:1216 小时前
java基础
java·开发语言
唐青枫7 小时前
C#.NET ThreadLocal 深入解析:线程独享数据、性能收益与实战边界
c#·.net
SilentSamsara7 小时前
Python 环境搭建完整指南:从下载安装到运行第一个程序
开发语言·python
小短腿的代码世界7 小时前
Qt文件系统与IO深度解析:从QFile到异步文件操作
开发语言·qt
harder3219 小时前
RMP模式的创新突破
开发语言·学习·ios·swift·策略模式
jinanwuhuaguo9 小时前
OpenClaw工程解剖——RAG、向量织构与“记忆宫殿”的索引拓扑学(第十三篇)
android·开发语言·人工智能·kotlin·拓扑学·openclaw
Rust研习社9 小时前
使用 Axum 构建高性能异步 Web 服务
开发语言·前端·网络·后端·http·rust