当前位置: 首页 > news >正文

改善C#代码的一些方法

  1. IEnumerable<T>:用于内存中的集合操作,支持延迟执行,但不支持复杂的查询优化。

    IQueryable<T>:用于与外部数据源(如数据库)交互,支持表达式树和查询优化,但依赖于特定的查询提供者。

  2. 如果局部变量的类型显而易见,则应该优先考虑使用var

  3. as运算符和is运算符只会判断对象的类型,不会执行其他操作,如果对象不是目标类型或其派生类型会失败。

    as失败会返回null,而不会抛出异常

    强制类型转换(cast)在遇到null时不会抛出异常,但需要处理两种特殊情况:对象本身为null和对象无法转换为目标类型时抛出异常。

    as运算符在这两种特殊情况下的结果都是null,因此只需if(t != null)语句来处理

  4. 内插字符串:$符号配花括号(花括号可内置三目运算、表达式、LINQ等等)

  5. nameof代替硬编码

  6. 用委托表示回调

    class Program
    {static void Main(){// 创建委托Action sayHello = () => Console.WriteLine("你好!");// 加上回调:先打招呼,然后做别的事CallWithCallback(sayHello);}static void CallWithCallback(Action callback){Console.WriteLine("准备打招呼...");// 这里调用回调方法callback();  // 回调执行:你好!Console.WriteLine("打招呼完成!");}
    }
    

​ 设计API时的应用:可在方法的参数中设计添加委托参数(即将方法传入方法,在方法中使用传入的方法)

  • 让用户提供——无参数操作:Action
  • 让用户提供——带参数:Action< >
  • 让用户提供——判断条件:Func<T, bool>
  1. 多线程触发事件,直接判断事件是否为 null可能因事件被取消订阅而出现NullReferenceException
    应使用 ?.Invoke 方式

  2. 装箱:把值类型转换成引用类型
    解除装箱:将装有值类型的引用类型转换成值类型
    应尽量避免把值类型转换成Object类型

  3. 需要多个构造函数时尽量使用链式调用,而不是让所有的构造函数调用同一段代码

     // 主构造函数
    public Example(int a, int b)
    {// 这里可以添加一些初始化代码
    }// 第一个构造函数,调用主构造函数
    public Example(int a) : this(a, 0)
    {
    }// 第二个构造函数,调用主构造函数
    public Example() : this(0, 0)
    {
    }
    
  4. 频繁被调用的方法内尽量不要new对象,改用成员变量复用对象,减轻垃圾回收器(GC)的工作负担

  5. 字符串是不可变类型,创建后进行±操作时,会创建多个临时字符串对象,产生垃圾,低效。

    应该考虑使用StringBuilder (1000次±拼接耗时0.5s)

  6. 永远不要在构造函数里调用虚函数

  7. 抽象类:不能被实例化,只能被继承。
    作用:强制规范(子类必须实现父类声明的方法),可以统一处理不同类型的对象

  8. 编写泛型时应使用约束(在使用方法前使用where

  9. 优先考虑提供迭代器方法,而不要返回集合 (数据量小的时候无需过度设计)

    • 可避免被修改数据。
    • 使用 yield return 实现的迭代器方法是延迟执行的。元素只在被遍历到的时候才会被生成。
    // 提供迭代器 - 延迟执行,按需生成
    public IEnumerable<int> GetAllNumbersLazily()
    {for (int i = 0; i < 1000000; i++){yield return CalculateExpensiveNumber(i); // 只在遍历到时才计算}
    }
    // 使用场景:调用者可能只需要前10个元素
    var numbers = GetAllNumbersLazily();
    foreach (var num in numbers.Take(10)) // 这里只会计算10次!
    {Console.WriteLine(num);
    }
    // 剩下的999,990个数字根本不会被计算,节省了大量资源。
    
  10. 优先考虑使用查询语句代替命令式结构

    如:

    var ans = ( from n in Enumerable.Range( 0 , 100 ) select n * n ).ToArray();
    

    Enumerable.Range()左闭右开的规则

    声明式写法举例:

    private static IEnumerable<Tuple<int, int>> QueryIndices3() {return from x in Enumerable.Range(0, 100)          // 数据源1from y in Enumerable.Range(0, 100)          // 数据源2(笛卡尔积)where x + y < 100                           // 过滤条件orderby (x*x + y*y) descending              // 排序(按到原点距离降序)select Tuple.Create(x, y);                  // 结果投影
    }
    

    所有主流语言的标准库都提供了高度优化的基础算法,其可靠性和性能是手写代码难以超越的。

http://www.jsqmd.com/news/571060/

相关文章:

  • 把YOLOv11检测做成Web服务:FastAPI + Docker一键部署,Windows/Mac宿主机都能远程访问
  • 手把手教你用IP查询工具提升CDN加速节点命中率
  • IOPaint:AI图像修复工具的高效部署与应用指南
  • 思源宋体深度探索:跨语言字体设计的哲学与实践
  • 企业级Web会话录制系统:完整架构设计与战略实施指南
  • Qwen3-VL-WEBUI插件系统:功能扩展开发实战
  • 幽灵依赖终结者:pnpm 的 node_modules 结构隔离深度解析
  • QAnything提示词工程:提升PDF问答准确率的秘诀
  • 如何将单机游戏变身为本地多人派对:Nucleus Co-Op 完全指南
  • 适用发质护发素推荐:4款针对油性发质的精选 - 博客万
  • 新手入门指南:在快马平台用万文通思路打造你的第一个文本转换网页
  • 【ETestDEV5教程27】ICD管理
  • 告别局域网限制:用WinSCP+Cpolar实现异地Windows与Ubuntu文件互传(保姆级图文)
  • 三步搞定图片批量处理:PowerToys Image Resizer让你的工作效率翻倍
  • 零成本发顶刊!回响数据助力学者研究成果荣登JCR1区权威期刊
  • 如何利用离线OCR工具实现高效文本提取:Umi-OCR全场景应用指南
  • 2025小红书跳转卡片技术揭秘:从逆向分析到服务器端自动化部署
  • PyTorch 2.8镜像开发者案例:独立游戏开发者生成角色动画视频素材
  • LeetCode热题100 每日温度
  • C# WinForm程序退出时如何避免内存泄漏?5种方法实测对比
  • Wan2.2-I2V-A14B参数详解:--duration/--resolution设置对显存影响实测
  • 网络爬虫主流思路及反爬破解技术应用(新手速成)
  • 3个高效方案:解决Realtek 8852BE Wi-Fi 6开源驱动问题
  • 小白也能懂:用Qwen3-TTS打造个人专属语音翻译工具
  • 告别玄学调参:手把手教你用STM32F103和MPU9250实现稳定的EKF姿态解算(附源码)
  • Video2X:用AI魔法将低分辨率视频变成4K超清大片的终极指南
  • Graphic Walker最佳实践:从数据预处理到可视化发布的完整工作流
  • KK键盘 v3.9.4-解锁去广告版!
  • 3步掌握AntiMicroX:让游戏手柄变身全能控制中心
  • PyTorch 2.8镜像多场景:支持图文多模态(Qwen-VL)、视频(Wan2.2)双引擎