🌹欢迎来到《小5讲堂》🌹
🌹这是《C#》系列文章,每篇文章将以博主理解的角度展开讲解。🌹
🌹温馨提示:博主能力有限,理解水平有限,若有不对之处望指正!🌹

在这里插入图片描述

目录

  • 前言
  • 数据类型
  • 重现报错
  • C#开发小技巧
    • 1. 使用 `nameof` 运算符代替字符串
    • 2. 使用 `??` 和 `??=` 简化空值检查
    • 3. 模式匹配简化类型检查
    • 4. 使用 `using` 声明简化资源管理
    • 5. 字符串操作优化
    • 6. 集合初始化简化
    • 7. 使用 `ValueTuple` 简化多返回值
    • 8. 使用 `Span<T>` 提高性能
    • 9. 使用 `record` 类型简化不可变对象
    • 10. 使用 `IAsyncEnumerable` 处理异步流
    • 11. 使用 `Null条件运算符` 安全访问成员
    • 12. 使用 `本地函数` 封装逻辑
    • 13. 使用 `switch表达式` 简化条件判断
    • 14. 使用 `全局using指令` (C# 10+)
  • 推荐文章

前言

一般使用成熟框架进行实体类转换一般很少出现这种类型报错的情况,突然出现这种报错还是有点小疑惑。
经过排查发现,原来是前端传递过来的雪花ID值,控制器接收的前端传递过来的值,实体类在反射时数据类型变为其他,导致在获取值时报错,类型不匹配,一起来看看如何解决这个问题。

数据类型

刚开始以为是同一个实体类同一个字段数据类型问题,后来发现并不是,Int64和long是可以解析的,没问题。
今天在改成昨天报错的情况,发现没有报错了,验证了Int64和long并不是报错的关键,下面进行错误重现。

重现报错

其实就是两个不同实体类搞错了,比如,反射了A实体类,却获取实体类B的值,这个时候就会提示报错。
下面,创建一个实体类

public class TestModel
{public long ID { get; set; }public string Name { get; set; }
}public class TestModel2
{public long ID { get; set; }public string Name { get; set; }
}

反射代码

var model = new TestModel();
model.ID = 1909528946437918720;
model.Name = "老张出场";var model2 = new TestModel();
model.ID = 1909528946437918721;
model.Name = "假冒老张";Type typeModel = typeof(TestModel);
PropertyInfo[] proModel = typeModel.GetProperties();
foreach (PropertyInfo pi in proModel)
{string dataType = pi.PropertyType.Name;string key = pi.Name;pi.GetValue(model2, null);
}

在这里插入图片描述
在这里插入图片描述

从上面就可以看到,小细节不注意的话,很容易把两个看着相似的实体类搞混了,所以,在命名实体类时尽量要有差异,否则就容易出现上面的情况。

C#开发小技巧

以下是一些实用的 C# 开发技巧,可以提高你的编码效率和代码质量:

1. 使用 nameof 运算符代替字符串

// 旧方式
Console.WriteLine("变量名: " + "myVariable");
// 新方式
Console.WriteLine("变量名: " + nameof(myVariable));

优势:重构友好,避免拼写错误

2. 使用 ????= 简化空值检查

// 旧方式
string name = (value != null) ? value : "default";
// 新方式
string name = value ?? "default";// 旧方式
if (list == null) {list = new List<string>();
}
// 新方式
list ??= new List<string>();

3. 模式匹配简化类型检查

// 旧方式
if (obj is MyClass) {var myObj = (MyClass)obj;// 使用myObj
}
// 新方式
if (obj is MyClass myObj) {// 直接使用myObj
}// switch表达式
var result = obj switch {int i when i > 0 => "正数",int i when i < 0 => "负数",_ => "零或其他"
};

4. 使用 using 声明简化资源管理

// 旧方式
using (var stream = new FileStream(...))
{// 使用stream
}
// 新方式
using var stream = new FileStream(...);
// 使用stream
// 离开作用域时自动释放

5. 字符串操作优化

// 字符串插值
var message = $"Hello, {name}! Today is {DateTime.Now:yyyy-MM-dd}";// 多行字符串
var json = """{"name": "John","age": 30}""";// 字符串拼接优化
var sb = new StringBuilder();
sb.Append("Hello");
sb.Append(" World");
var result = sb.ToString();

6. 集合初始化简化

// 旧方式
var list = new List<int>();
list.Add(1);
list.Add(2);
list.Add(3);// 新方式
var list = new List<int> { 1, 2, 3 };// 字典初始化
var dict = new Dictionary<string, int> {["one"] = 1,["two"] = 2
};

7. 使用 ValueTuple 简化多返回值

// 旧方式
public void GetValues(out int x, out int y) { ... }
// 调用
int x, y;
GetValues(out x, out y);// 新方式
public (int x, int y) GetValues() { ... }
// 调用
var (x, y) = GetValues();

8. 使用 Span<T> 提高性能

// 处理数组子集
var array = new int[100];
var slice = new Span<int>(array, 10, 20); // 引用array的10-30元素
foreach (ref int item in slice) {item *= 2;
}

9. 使用 record 类型简化不可变对象

// 旧方式
public class Person {public string Name { get; }public int Age { get; }// 构造函数、Equals、GetHashCode等...
}// 新方式
public record Person(string Name, int Age);// 使用
var person = new Person("John", 30);
var newPerson = person with { Age = 31 }; // 不可变修改

10. 使用 IAsyncEnumerable 处理异步流

public async IAsyncEnumerable<int> GetNumbersAsync() {for (int i = 0; i < 10; i++) {await Task.Delay(100);yield return i;}
}// 使用
await foreach (var number in GetNumbersAsync()) {Console.WriteLine(number);
}

11. 使用 Null条件运算符 安全访问成员

// 旧方式
if (person != null && person.Address != null) {var city = person.Address.City;
}
// 新方式
var city = person?.Address?.City;

12. 使用 本地函数 封装逻辑

public void ProcessData(List<int> data) {// 本地函数int Square(int x) => x * x;var results = data.Select(Square).ToList();
}

13. 使用 switch表达式 简化条件判断

// 旧方式
string GetSizeDescription(int size) {if (size < 10) return "Small";else if (size < 20) return "Medium";else return "Large";
}// 新方式
string GetSizeDescription(int size) => size switch {< 10 => "Small",< 20 => "Medium",_ => "Large"
};

14. 使用 全局using指令 (C# 10+)

// 在项目文件中添加
<ItemGroup><Using Include="System.Linq" /><Using Include="System.Collections.Generic" />
</ItemGroup>
// 或者在GlobalUsings.cs中
global using System.Linq;
global using System.Collections.Generic;

这些技巧可以帮助你编写更简洁、更高效、更易维护的C#代码。根据不同的C#版本,部分功能可能需要特定版本支持。

推荐文章

【C#】实体类定义的是long和值识别到的是Int64,实体类反射容易出现Object does not match target type

【C#】如果有一个数值如 168.0000100,如何去除末尾的无效零,只显示有效的小数位数,让DeepSeek给我们解答

【C#】Quartz.NET怎么动态调用方法,并且根据指定时间周期执行,动态配置类何方法以及Cron表达式,有请DeepSeek

【C#】.net core6.0无法访问到控制器方法,直接404。由于自己的不仔细,出现个低级错误,这让DeepSeek看出来了,是什么错误呢,来瞧瞧

【C#】Html转Pdf,Spire和iTextSharp结合,.net framework 4.8

【C#】事务(进程 ID 64)与另一个进程被死锁在锁资源上,并且已被选作死锁牺牲品。请重新运行该事务。不能在具有唯一索引“XXX_Index”的对象“dbo.Test”中插入重复键的行。

【C#】使用DeepSeek帮助评估数据库性能问题,C# 使用定时任务,每隔一分钟移除一次表,再重新创建表,和往新创建的表追加5万多条记录

【C#】合理使用DeepSeek相关AI应用为我们提供强有力的开发工具,在.net core 6.0框架下使用JsonNode动态解析json字符串,如何正确使用单问号和双问号做好空值处理

【C#】已经实体类和动态实体类的反射使用方法,两分钟回顾,码上就懂

【C#】使用vue3的axios发起get和post请求.net framework部署的API显示跨域

【C#】.net core 6.0 webapi 使用core版本的NPOI的Excel读取数据以及保存数据

【C#】pdf按页分割文件,以及分页合并,效果还不错,你值得拥有

【C#】未能加载文件或程序集“CefSharp.Core.Runtime.dll”或它的某一个依赖项。找不到指定的模块。

【C#】.net core 6.0 在program时间格式统一json格式化,并列举program默认写法和简化写法

【C#】.net core 6.0 ApiController,API控制器方法,API接口以实体类作为接收参数应该注意的点

【C#】 SortedDictionary,查找字典中是否存在给定的关键字

【C#】.net core 6.0 MVC返回JsonResult显示API接口返回值不可被JSON反序列化

【C#】.net core 6.0 使用第三方日志插件Log4net,配置文件详细说明

【C#】使用代码实现龙年春晚扑克牌魔术(守岁共此时),代码实现篇

【C#】使用代码实现龙年春晚扑克牌魔术(守岁共此时),流程描述篇

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/89249.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/89249.shtml
英文地址,请注明出处:http://en.pswp.cn/bicheng/89249.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C#获取当前系统账户是否为管理员账户

传统方式&#xff1a;WindowsPrincipal winPrincipal new WindowsPrincipal(WindowsIdentity.GetCurrent()); bool admin winPrincipal.IsInRole(WindowsBuiltInRole.Administrator);这种方式虽然是最常用的检测管理员权限的方法&#xff0c;但是有个致命的缺陷&#xff0c;就…

【c++深入系列】:万字详解list(附模拟实现的list源码)

&#x1f525; 本文专栏&#xff1a;c &#x1f338;作者主页&#xff1a;努力努力再努力wz &#x1f4aa; 今日博客励志语录&#xff1a; 当你觉得累的时候&#xff0c;说明你在走上坡路 ★★★ 本文前置知识&#xff1a; 模版 那么在之前的学习中&#xff0c;我们已经学习了…

PandaWiki与GitBook深度对比:AI时代的知识管理工具,选谁好?

在当今信息爆炸的时代&#xff0c;知识管理工具已成为个人学习、团队协作和企业文档管理的必需品。PandaWik作为AI时代迅速崛起的广受欢迎知识管理平台&#xff0c;代表了新一代AI驱动的知识库系统。本文将从功能特性、技术架构、适用场景等多个维度进行全面对比分析。产品定位…

清除 Android 手机 SIM 卡数据的4 种简单方法

SIM 卡存储了联系人、短信和通话记录等信息。在更换新 SIM 卡之前&#xff0c;彻底清除旧卡上的所有个人数据&#xff08;如 SIM 卡联系人、短信、通话记录和手机号码&#xff09;非常重要。要在 Android 手机上清除 SIM 卡内存&#xff0c;您可以参考以下方法。但在开始之前&a…

算法学习笔记:20.分治法——从原理到实战,涵盖 LeetCode 与考研 408 例题

分治法&#xff08;Divide and Conquer&#xff09;是计算机科学中最经典的算法设计思想之一&#xff0c;其核心思想是将复杂问题分解为若干个规模较小的子问题&#xff0c;通过解决子问题并合并结果来求解原问题。这种思想不仅在排序、搜索等基础算法中广泛应用&#xff0c;也…

@classmethod

1. 基本概念 classmethod 是 Python 中用于定义类方法的一种装饰器。类方法与常规的实例方法不同&#xff0c;它的第一个参数是 cls&#xff0c;表示类本身&#xff0c;而不是实例。 class MyClass:class_attr "Class Attribute"classmethoddef class_method(cls):p…

Qt 中使用 SQLite 数据库

一、SQLite 数据库介绍 SQLite 是一个轻量级的嵌入式关系型数据库管理系统&#xff0c;它以库的形式提供&#xff0c;不需要单独的服务器进程&#xff0c;直接访问存储在普通磁盘文件中的数据库。 主要特性 无服务器架构&#xff1a;SQLite 不需要单独的服务器进程 零配置&a…

【Unity】IL2CPP相关理论知识学习

一种编译技术。优点&#xff1a;性能优化&#xff1a;IL2CPP生成C代码后由本地编译器优化&#xff0c;一般在CPU性能和GC方面都优于Mono。特别在移动端或主机平台&#xff0c;性能差距更加明显。跨平台支持&#xff1a;Unity作为跨平台引擎&#xff0c;IL2CPP是支持iOS、Androi…

一个用于在 Ubuntu 22.04.3 LTS 上显示文件系统超级块信息的 C 程序

1.程序#include <stdio.h> #include <sys/statvfs.h> #include <errno.h>int main(int argc, char *argv[]) {const char *path;struct statvfs fs_info;// 检查参数if (argc ! 2) {fprintf(stderr, "用法: %s <挂载点或路径>\n", argv[0]);…

Git未检测到文件更改

背景 在本地仓库改动文件发现git检测不到修改了的文件&#xff0c;安装有Git状态可视化工具&#xff0c;文件改动后应该是红色标记&#xff0c;但是仍然是绿色的 git status&#xff0c;git diff等也都没有显示文件改动 原因 1.可能是文件命中了.gitignore文件过滤条件 检查后发…

Golang学习之常见开发陷阱完全手册

1. 指针的“温柔陷阱”&#xff1a;空指针与野指针的致命一击Go语言的指针虽然比C/C简单&#xff0c;但照样能让你“痛不欲生”。新手常觉得Go的指针“安全”&#xff0c;但真相是&#xff1a;Go并不会帮你完全规避指针相关的Bug。空指针&#xff08;nil pointer&#xff09;和…

【python】sys.executable、sys.argv、Path(__file__) 在PyInstaller打包前后的区别

文章目录sys.executable 的区别打包前打包后sys.argv 的区别打包前打包后Path(__file__) 的区别打包前打包后应用场景与解决方案总结在使用 PyInstaller 将 Python 脚本打包为独立可执行文件时&#xff0c; sys.executable、 sys.argv 和 Path(__file__) 的行为会发生变化。理…

JWT基础详解

JSON Web Token 简称JWT 一、起源&#xff1a; 这一切的起源都源于网景公司的一个天才程序员&#xff0c;为了解决http协议无状态问题&#xff0c;就让浏览器承担了一部分“记忆”责任&#xff08;每次客户端&#xff0c;访问服务器&#xff0c;自身就携带cookie&#xff0c;…

【Unity】MiniGame编辑器小游戏(十四)基础支持模块(游戏窗口、游戏对象、物理系统、动画系统、射线检测)

更新日期:2025年7月15日。 项目源码:获取项目源码 索引 基础支持模块一、游戏窗口 MiniGameWindow1.窗体属性2.快速退出键3.模拟帧间隔时间4.生命周期函数5.游戏状态二、游戏对象 MiniGameObject1.位置2.激活状态3.碰撞器4.限制游戏对象的位置5.生命周期函数6.移动三、物理系…

Swift6.0 - 5、基本运算符

目录1、术语2、赋值运算符&#xff08;a b&#xff09;3、算术运算符&#xff08;、-、*、/&#xff09;3.1、余数运算符&#xff08;%&#xff09;3.2、一元负号运算符&#xff08;-a&#xff09;3.3、一元正号运算符&#xff08;a&#xff09;4、复合赋值运算符&#xff08;…

DataWhale AI夏令营 Task2.2笔记

本次代码改进主要集中在聚类算法和主题词提取方法的优化上&#xff0c;主要包含三个关键修改&#xff1a;首先&#xff0c;将聚类算法从KMeans替换为DBSCAN。这是因为原KMeans方法需要预先指定聚类数量&#xff0c;而实际评论数据中的主题分布难以预测。DBSCAN算法能够自动确定…

自启动策略调研

广播拦截策略1.流程图广播发送├─ 特权进程&#xff08;Root/Shell&#xff09; → 放行├─ 系统进程&#xff08;UID≤1000&#xff09; → 自动启动校验 → 非法广播&#xff1f; → 拦截│ ├─ 黑名单匹配 → 拦截│ └─ 用户/白名单校验 → 受限用户&#xff1f; →…

MFC/C++语言怎么比较CString类型最后一个字符

文章目录&#x1f527; 1. 直接下标访问&#xff08;高效首选&#xff09;&#x1f50d; 2. ReverseFind 反向定位&#xff08;语义明确&#xff09;✂️ 3. Right 提取子串&#xff08;需临时对象&#xff09;⚙️ 4. 封装工具函数&#xff08;推荐健壮性场景&#xff09;⚠️…

【Cortex-M】异常中断时的程序运行指针SP获取,及SCB寄存器错误类型获取

【Cortex-M】异常中断时的程序运行指针SP获取&#xff0c;及SCB寄存器错误类型获取 更新以gitee为准&#xff1a; gitee 文章目录异常中断异常的程序运行指针SP获取SCB寄存器错误类型获取硬件错误异常 Hard fault status register (SCB->HFSR)存储器管理错误异常 SCB->C…

项目流程管理系统使用建议:推荐13款

本文分享了13款主流的项目流程管理系统&#xff0c;包括&#xff1a;1.PingCode&#xff1b;2.Worktile&#xff1b;3.泛微 E-Office&#xff1b;4.Microsoft Project&#xff1b;5.简道云&#xff1b;6.Zoho Projects&#xff1b;7.Tita 项目管理&#xff1b;8.Oracle Primave…