C#中匿名类型的相等性比较陷阱(Equals重写机制大揭秘)

第一章:C#中匿名类型的相等性比较陷阱(Equals重写机制大揭秘)

在C#中,匿名类型常用于LINQ查询或临时数据封装,其语法简洁、使用方便。然而,开发者在进行相等性比较时常常陷入误区,尤其是在依赖默认的Equals行为时。

匿名类型的相等性规则

C#为匿名类型自动生成重写的Equals(object)和GetHashCode()方法。两个匿名类型实例相等当且仅当:
  • 它们的属性数量相同
  • 属性名称和声明顺序完全一致
  • 对应属性的值通过Object.Equals判定相等
// 示例:匿名类型的相等性比较
var obj1 = new { Name = "Alice", Age = 30 };
var obj2 = new { Name = "Alice", Age = 30 };
var obj3 = new { Age = 30, Name = "Alice" }; // 属性顺序不同

Console.WriteLine(obj1.Equals(obj2)); // 输出: True
Console.WriteLine(obj1.Equals(obj3)); // 输出: False(顺序影响相等性)
注意:尽管obj1和obj3包含相同的属性和值,但由于声明顺序不同,.NET生成的类型被视为不同,导致比较结果为False。

编译时类型与运行时行为

匿名类型在编译时由编译器生成唯一的内部类名,并自动实现Equals和GetHashCode。该机制基于属性的“值语义”而非引用语义。 以下表格展示了不同场景下的比较结果:
实例定义Equals结果说明
new { X = 1 } vs new { X = 1 }True属性名、顺序、值均相同
new { A = 1, B = 2 } vs new { B = 2, A = 1 }False属性顺序不同,视为不同类型
new { Name = "Tom" } vs new { Name = "tom" }False值不相等(区分大小写)
理解这一机制有助于避免在集合去重、字典键查找等场景中出现意外行为。建议在需要稳定相等性逻辑时优先使用命名记录类型(record),以获得更可预测的行为。

第二章:匿名类型与Equals方法的底层机制

2.1 匿名类型的编译时生成规则与IL分析

C# 中的匿名类型在编译时由编译器自动生成一个不可见的类,该类包含只读属性和重写的 `Equals`、`GetHashCode` 方法。其生成遵循严格的命名与结构规则。
匿名类型的语法与等价结构
var person = new { Name = "Alice", Age = 30 };
上述代码会被编译器转换为类似以下的具名类型:
internal sealed class <>f__AnonymousType0<T1, T2>
{
    public string Name { get; }
    public int Age { get; }

    public <>f__AnonymousType0(string name, int age)
    {
        Name = name;
        Age = age;
    }

    public override bool Equals(object other);
    public override int GetHashCode();
}
编译器确保相同属性名、顺序和类型的匿名对象复用同一生成类型。
IL 层面的关键特征
  • 类型名称以 `<>f__AnonymousType` 开头,保证源级不可见
  • 所有属性通过自动属性生成,背后对应私有字段
  • `GetHashCode` 基于所有字段值联合计算,支持集合中的正确比较

2.2 默认Equals方法如何实现属性级比较

在面向对象编程中,`Equals` 方法用于判断两个对象是否相等。默认实现通常基于引用比较,但在需要属性级对比时,需重写该方法以逐字段比较值。
属性级比较的实现逻辑
重写 `Equals` 时,应遍历对象的所有关键属性,确保类型相同且各属性值相等。

public boolean equals(Object obj) {
    if (this == obj) return true;
    if (!(obj instanceof User)) return false;
    User other = (User) obj;
    return Objects.equals(this.name, other.name) &&
           Objects.equals(this.age, other.age);
}
上述代码首先检查引用同一性,再确认类型一致性,最后使用 `Objects.equals` 安全比较字符串和数值属性,避免空指针异常。
常用工具辅助比较
  • Java 中可借助 `Objects.equals` 处理 null 值
  • C# 可使用记录类型(record)自动实现值语义比较
  • 手动实现时需同步重写 `GetHashCode` 以保持契约一致

2.3 GetHashCode的自动生成策略及其影响

在 .NET 中,当未重写 `GetHashCode` 时,CLR 会基于对象的运行时身份自动生成哈希码。这一策略确保了同一对象在生命周期内返回一致的哈希值,适用于引用类型默认行为。
自动生成机制
系统通过对象头中的“同步块索引”或内存地址生成唯一哈希码,保证进程内唯一性。但值类型若未重写,将使用基类 `ValueType` 的反射实现,性能较低。
性能与陷阱
  • 频繁调用可能导致性能瓶颈,尤其在哈希表操作中
  • 对象迁移(如GC移动)后仍需保持哈希一致性
  • 可变字段参与哈希计算易导致字典查找失败
public override int GetHashCode()
{
    // 使用系统默认算法
    return base.GetHashCode(); 
}
该代码调用父类实现,适用于需保留引用身份语义的场景。参数无须输入,返回值由运行时环境决定,依赖内部对象标识机制。

2.4 引用类型与值语义的冲突场景剖析

在Go语言中,结构体默认按值传递,但当字段包含引用类型(如切片、map、指针)时,值复制仅复制引用本身,而非底层数据,从而引发意外的数据共享。
典型冲突示例
type User struct {
    Name string
    Tags []string
}

u1 := User{Name: "Alice", Tags: []string{"go", "dev"}}
u2 := u1  // 值复制,但Tags仍指向同一底层数组
u2.Tags[0] = "rust"
fmt.Println(u1.Tags) // 输出:[rust dev],意外被修改
上述代码中,u2 := u1 执行的是浅拷贝,Tags 字段作为切片(引用类型)在两个实例间共享底层数组,导致对 u2.Tags 的修改影响了 u1。
规避策略对比
策略实现方式适用场景
深度拷贝手动复制引用字段结构简单,性能要求低
构造函数封装NewUser 返回独立实例频繁创建场景
使用不可变类型避免暴露内部切片高并发安全需求

2.5 反射验证Equals重写行为的实验演示

在面向对象编程中,equals 方法的正确重写对对象比较至关重要。通过反射机制,可在运行时动态检测该方法是否被正确覆盖。
实验设计思路
创建两个类:一个未重写 equals,另一个正确重写。使用反射获取 equals 方法并分析其声明类。

Method equalsMethod = obj.getClass().getMethod("equals", Object.class);
boolean isOverridden = !equalsMethod.getDeclaringClass().equals(Object.class);
上述代码通过 getDeclaringClass() 判断方法来源。若返回非 Object.class,说明已被重写。
结果验证表格
类名equals被重写反射检测结果
PlainEntity否False
CustomEntity是True

第三章:相等性比较中的常见陷阱案例

3.1 跨程序集匿名类型不兼容问题实战

在.NET中,匿名类型常用于LINQ查询结果封装,但其作用域被限制在定义它的程序集内。当跨程序集传递时,即使结构完全相同,编译器也会视为不同类型。
问题复现场景
// 程序集A
var user = new { Id = 1, Name = "Alice" };

// 程序集B(引用A)
var other = new { Id = 1, Name = "Alice" };
Console.WriteLine(user.Equals(other)); // 输出:False
尽管两个对象结构一致,但由于匿名类型由编译器在各自程序集中独立生成,其内部类型名包含程序集标识,导致实际类型不等价。
解决方案对比
  • 使用公共程序集中的具名类替代匿名类型
  • 通过接口抽象共享数据契约
  • 利用dynamic进行动态属性访问(需权衡性能与安全性)
方案类型安全性能
具名类强类型高
dynamic弱类型较低

3.2 属性顺序对Equals结果的影响测试

在对象比较中,属性的定义顺序是否会影响 `Equals` 方法的结果是一个值得验证的问题。本节通过构造两个具有相同属性但声明顺序不同的类实例进行测试。
测试用例设计
使用 C# 创建两个类实例,属性顺序相反:

public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}
// 实例1: 先Name后Age,实例2: 先Age后Name(编译后结构一致)
CLR 编译后类型结构由元数据决定,而非源码顺序。因此,属性声明顺序不影响运行时对象的字段布局。
Equals 方法行为分析
  • 引用类型默认 Equals 比较的是实例引用
  • 值语义需重写 Equals 和 GetHashCode
  • 属性顺序不改变哈希码计算逻辑
实验表明:只要属性值相同且正确实现相等性逻辑,顺序差异不会影响比较结果。

3.3 null值处理与装箱带来的意外行为

在Java等语言中,基本类型与其包装类之间的自动装箱机制虽然提升了编码便利性,但也引入了潜在风险,尤其是在涉及null值时。
装箱与空指针陷阱
当对一个值为null的包装类型变量进行拆箱操作时,会触发NullPointerException:

Integer value = null;
int result = value; // 运行时抛出 NullPointerException
上述代码中,尽管value是Integer类型,但在赋值给int时会自动拆箱,调用value.intValue(),从而引发异常。
常见规避策略
  • 优先使用基本类型避免null问题
  • 在拆箱前进行null检查
  • 使用Optional<Integer>表达可选值语义
通过合理设计数据类型和防御性编程,可有效规避此类运行时异常。

第四章:规避陷阱的最佳实践与替代方案

4.1 使用记录类型(record)实现安全相等比较

在现代编程语言中,记录类型(record)为值对象的相等性比较提供了语义清晰且类型安全的机制。与传统的引用比较不同,记录类型默认基于结构相等性进行判断,即当两个记录的所有字段值相等时,它们被视为逻辑上相等。
记录类型的定义与用法
以 C# 为例,使用 record 关键字声明不可变数据类型:
public record Person(string Name, int Age);
该定义自动生成基于值的 Equals、GetHashCode 和 ToString 方法,确保比较时不会误判引用地址。
相等性比较的语义优势
  • 避免了引用类型默认的内存地址比较
  • 支持深度值比较,适用于嵌套记录结构
  • 提升代码可读性与领域建模准确性
通过编译器生成的等值逻辑,开发者无需手动实现复杂的比较方法,显著降低出错概率。

4.2 手动重写Equals与GetHashCode的规范写法

在C#中,当需要基于值语义比较对象时,必须同时重写 `Equals` 和 `GetHashCode` 方法,以确保在哈希集合(如 `Dictionary`、`HashSet`)中的正确行为。
核心原则
  • 若两个对象的 `Equals` 返回 true,则它们的 `GetHashCode` 必须返回相同值
  • 不可变字段应作为哈希计算的基础,避免运行时哈希值变化
标准实现模板
public override bool Equals(object obj)
{
    if (obj is Person other)
        return Id == other.Id && Name == other.Name;
    return false;
}

public override int GetHashCode()
{
    return HashCode.Combine(Id, Name);
}
上述代码中,`HashCode.Combine` 是 .NET Core 引入的高效方法,自动处理多个字段的哈希合并。`Equals` 使用 `is` 模式匹配提升可读性与性能。只有当类的所有参与比较的属性均为只读或不变时,该实现才是安全的。

4.3 利用IEquatable<T>提升性能与类型安全

在.NET中,实现IEquatable<T>接口可显著提升值类型和引用类型的相等性比较效率与类型安全性。
避免装箱与提升性能
对于值类型,重写Object.Equals会导致装箱操作。通过实现IEquatable<T>,可避免此开销:
public struct Point : IEquatable<Point>
{
    public int X { get; }
    public int Y { get; }

    public Point(int x, int y) => (X, Y) = (x, y);

    public bool Equals(Point other) => X == other.X && Y == other.Y;

    public override bool Equals(object obj) => 
        obj is Point p && Equals(p);

    public override int GetHashCode() => HashCode.Combine(X, Y);
}
Equals(Point)直接进行值比较,无需装箱,提升性能。
增强类型安全
IEquatable<T>在编译时检查类型匹配,防止运行时类型错误。泛型集合如Dictionary<TKey, TValue>会优先调用该接口方法,确保高效且安全的比较逻辑。

4.4 单元测试中验证相等逻辑的可靠模式

在单元测试中,验证对象或数据结构的相等性是确保逻辑正确性的核心环节。直接使用语言内置的相等操作符可能忽略语义一致性,导致误判。
使用深度比较断言
多数测试框架提供深度比较功能,能递归比对复杂结构:

expected := User{Name: "Alice", Age: 30}
actual := GetUser()
assert.Equal(t, expected, actual) // 断言字段值完全一致
assert.Equal 使用反射进行字段级比对,适用于结构体、切片等复合类型,避免浅比较遗漏嵌套差异。
自定义相等判断逻辑
当需忽略某些字段(如时间戳)时,可实现自定义比较:
  • 使用 cmp 库的选项机制排除特定字段
  • 通过 Comparer 注入自定义比较函数

opt := cmp.Comparer(func(x, y User) bool {
    return x.Name == y.Name && x.Age == y.Age
})
if diff := cmp.Diff(expected, actual, opt); diff != "" {
    t.Errorf("mismatch (-want +got):\n%s", diff)
}
该模式提升断言灵活性,确保业务语义上的“相等”被准确验证。

第五章:总结与扩展思考

性能优化的实战路径
在高并发系统中,数据库查询往往是性能瓶颈的源头。通过引入缓存层(如 Redis)并结合本地缓存(如 Go 的 sync.Map),可显著降低响应延迟。以下是一个带过期机制的缓存封装示例:

type CachedService struct {
    localCache sync.Map
}

func (s *CachedService) Get(key string) (string, bool) {
    if val, ok := s.localCache.Load(key); ok {
        return val.(string), true // 命中本地缓存
    }
    // 模拟从 Redis 获取
    result := fetchFromRedis(key)
    if result != "" {
        s.localCache.Store(key, result)
        time.AfterFunc(5*time.Minute, func() {
            s.localCache.Delete(key) // 5分钟后过期
        })
    }
    return result, result != ""
}
微服务架构中的容错设计
实际生产环境中,服务间调用必须考虑熔断与降级。Hystrix 或 Resilience4j 提供了成熟的解决方案。以下是常见策略对比:
策略适用场景恢复机制
熔断依赖服务频繁超时定时探测恢复
限流突发流量冲击滑动窗口重置
降级核心资源不足手动或健康检查触发
可观测性体系构建
现代系统必须具备完整的监控链路。推荐采用以下组件组合:
  • Prometheus:采集指标数据
  • Loki:日志聚合分析
  • Jaeger:分布式追踪请求链路
  • Grafana:统一可视化展示
通过 OpenTelemetry SDK 注入追踪上下文,可在跨服务调用中定位性能热点。某电商平台在接入后,将支付链路的平均排查时间从 45 分钟缩短至 8 分钟。
C# HashCode.Combine实战:如何避免手动计算哈希码的3大坑(附性能对比) 本文深入探讨了C#中手动实现GetHashCode方法的三大常见陷阱:碰撞率高、null处理复杂和代码冗余。通过对比分析,重点介绍了.NET Core 2.1引入的HashCode.Combine方法如何优雅地解决这些问题。文章提供了实战代码示例和性能对比数据,证明HashCode.Combine在保证低碰撞率的同时,具备自动处理null值、代码简洁和高性能的优势,是替代手动计算哈希码的最佳实践。 阅读详情

相关推荐

委托不是语法糖:.NET中类型安全的函数指针本质

委托是.NET运行时中具备完整元数据和调用契约的类型安全函数指针,其本质远超语法糖或接口简化——它作为第一等公民类型,支持堆分配、泛型约束与跨线程传递。底层基于MulticastDelegate引用类型实现多播、闭包捕获与GC生命周期管理,Invoke方法实为JIT委托调用桩的触发入口,直接影响性能与反射能力。在事件系统、异步编程(如Task.Run)、插件化架构及UI线程同步等场景中,委托承担着方法实体化、回调契约化与执行上下文化的关键角色。理解其内存布局、相等性规则与序列化限制,是规避NullRefer

diedangxiang4092的博客 412

两个DataRow是否相等,是否指向同一个DataRow

DataRow row1 = currentRow; DataTable dt = currentRow.Table.Clone(); dt.ImportRow(currentRow); DataRow row2 = dt.Rows[0]; ...

flyingdream123的专栏 1402

完整内、外期货量化交易系统源码可售

支持客户登录校验,支持所有的实时行情和汇总报价功能、实时资讯(报价,列表,分时,分钟成交明晰,),多线程支持盘后收盘作业下载(日线,5分钟线,15分钟, 30分钟,60分钟线,),支持从服务器下载相关运行配置(来自服务器动态配置信息,如收盘日期等),实现状态条显示。收盘作业包括日线、5分钟线、15分钟线、30分钟、60分钟线、2小时线、4小时线每日分时走势。综合信息栏显示用户账户信息、合约信息、当日委托单记录、当日成交记录、当日平仓记录、当日跟单记录、当日(月/周)排行榜、下单栏、持仓信息;

qq_35600909的博客 1805

c# 利用IEqualityComparer接口去除DataTable重复数据

IEqualityComparer主要适用于定义方法以支持对象的相等比较。可以实现集合的自定义相等比较。即,您可以创建自己的相等定义,并指定此定义与接受 IEqualityComparer 接口的集合类型一起使用。 IEqualityComparer 接口包含两个方法 Equals 确定指定的对象是否相等。 GetHashCode 返回指定对象的哈希代码。 整体来说,比较好理解 Eq...

Jane_9008的博客 418

Aruco标签定位、测距、三维位置估算 opencv应用

摄像头要一开始对准aruco标签才开始运行。+ 相机标定文件(参考我的上篇文章)+ aruco标签6*6。

dgut_guangdian的博客 4221

树莓派5安装ROS2小白指南避坑攻略

手把手教你如何在树莓派5上顺利安装ROS2,避开常见问题与陷阱,提升配置效率。针对树莓派5安装ros2过程中的依赖冲突、源配置错误等高频难题提供解决方案,适合新手快速上手。

weixin_35754962的博客 1005

C#教程:关于匿名类型的特性

首先让我们看一个例子, 假设我们并没有Person类, 并且我们关心的属性只有Name和Age. 下面的代码演示了我们如何在没有声明类型的情况下来构建一个对象的: 1: var tom = new { Name = Tom, Age = 4 }; 2: var holly = new { Name = Holly, Age = 31 }; 3: var jon = new { Na...

weixin_30840573的博客 243

876-基于STM32的毫米波雷达智能睡眠监测系统

基于STM32的毫米波雷达智能睡眠监测系统通过非接触式毫米波雷达检测人体呼吸频率和体动次数,结合WIFI数据传输和OLED显示,实现睡眠质量分析与远程监控。系统核心功能包括生理参数采集、阈值设置、数据可视化及远程交互。

m0_50083169的博客 1543

匿名类型Equals比较失效?5步排查法快速定位C#项目中的隐式陷阱

快速解决C#匿名类型Equals比较异常问题,通过5步排查法精准定位陷阱。涵盖常见应用场景与调试技巧,深入解析C#匿名类型的Equals重写机制,提升代码可靠性。方法实用高效,值得收藏。

DebugLoom的博客 948

LCD、LED、OLED、Mini LED、Micro LED、全阵列LED、QLED、QD-OLED、QNED、AMOLED是什么意思?

LCD(液晶显示器,Liquid Crystal Display)定义:LCD 是一种利用液晶材料控制光线通过的显示技术,需依靠背光源(如冷阴极荧光灯 CCFL 或 LED)照亮液晶层以形成图像。技术原理:液晶分子在电场作用下改变排列,控制背光通过的强度和颜色。液晶本身不发光,需外部光源。特点:结构包括背光层、液晶层、彩色滤光片和偏光片。响应时间较慢,黑色表现因背光漏光而偏灰。LED(发光二极管显示,Light Emitting Diode)定义。

中国最威武的城市!武功军威-武威,铁骨铮铮! 3427

STC8G1K08A 实战应用:从配置到功能实现

本文详细介绍了STC8G1K08A单片机的实战应用,从开发环境搭建、GPIO配置、ADC模块使用到定时器中断处理和PWM输出等核心功能。重点讲解了外设模块的协同工作配置技巧,并分享了实际项目开发中的经验教训,帮助开发者快速掌握STC8G1K08A的高效应用。

n4o5p6q7r的博客 391

Equals重写陷阱频发,匿名类型究竟该如何正确处理?

掌握匿名类型Equals重写正确方法,避免常见陷阱。适用于C#对象比较场景,通过重写Equals和GetHashCode确保逻辑一致性,提升代码健壮性。理解编译器自动生成行为与自定义实现差异,有效防止误判。实用技巧值得收藏。

DevPath的博客 278

VxWorks系列 快速导航

Vxworks系列快速阅览导航

Mr.Sugarcane 1308

为什么你的LINQ查询结果出错?Equals未重写导致的匿名类型比较陷阱

解决LINQ查询异常,揭秘匿名类型Equals未重写导致的比较陷阱。本文解析其在集合查找与去重场景下的影响,教你通过正确重写Equals方法确保相等性判断准确,提升代码可靠性,值得收藏。

DebugVibe的博客 252

【逐函数讲解ORB_SLAM3源码】获取普通帧率、关键帧、IMU数据

获得imu的旋转 mRwc * mImuCalib.mTcb.rotationMatrix(); Sophus::SE3 mTwc 创建ORB_SLAM3系统 Create SLAM system. It initializes all system threads and gets ready to process frames. ORB_SLAM3::System SLAM(argv[1],argv[2],ORB_SLAM3::System::IMU_RGBD, true, 0, file_nam

小秋 AI SLAM 入门实战教程 1245

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

【C#匿名类型Equals揭秘】:深入解析Equals重写原理与性能优化策略

深入解析C#匿名类型的Equals重写机制,揭示其自动生成的相等性比较逻辑与性能优化策略。涵盖编译器实现原理、引用与值相等判断场景及实际应用优势,助你高效掌握底层细节。值得收藏,点击了解完整原理。

CodeWhim的博客 362

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

【.NET开发必知】:匿名类型无法正确比较?Equals重写的5个关键要点

解决匿名类型比较难题,掌握Equals重写关键技巧。本文详解匿名类型Equals重写在LINQ查询与集合操作中的正确应用,涵盖相等性逻辑、性能优化与常见陷阱,助你提升代码可靠性与可维护性,值得收藏

PixelStream的博客 264

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

C#高级编程实战:匿名类型Equals重写避坑指南(资深架构师亲授)

解决匿名类型比较难题,掌握Equals重写关键技巧。本文详解C#中匿名类型Equals重写的适用场景与核心实现方法,揭示编译器自动生成的相等逻辑及避坑要点,提升代码健壮性与性能表现,值得收藏。

QuickCode的博客 377

匿名类型Equals重写全攻略(99%开发者忽略的关键细节)

掌握匿名类型 Equals 重写技巧,解决对象比较难题。涵盖自定义Equals方法、属性值对比逻辑与性能优化策略,适用于LINQ查询和集合操作场景。深入剖析编译器生成机制与常见误区,提升代码可靠性与执行效率,值得收藏。

Algorift的博客 300

C#高级编程技巧:实现匿名类型Equals重写的4步安全方案(稀缺实战经验)

掌握C#中匿名类型Equals重写的4步安全方案,解决对象比较难题。适用于LINQ查询与集合操作场景,通过反射与表达式树实现高效重写,确保类型安全与性能平衡。稀缺实战经验分享,值得收藏。

CodeVibe的博客 381

【.NET性能优化】:正确使用匿名类型Equals避免内存泄漏的3个实践

掌握C#匿名类型的Equals重写技巧,有效避免因哈希冲突导致的内存泄漏。适用于集合操作与缓存场景,通过正确重写Equals和GetHashCode提升性能与稳定性。3个实用实践方案,值得收藏。

StepNexus的博客 614

匿名类型Equals重写避坑指南:90%开发者忽略的引用与值语义混淆问题

解决匿名类型Equals重写中的值语义混淆问题,深入剖析C#中匿名类型Equals方法的默认行为与重写陷阱。涵盖实际应用场景、正确实现引用和值比较的核心方法,避免常见Bug。掌握这一细节,提升代码健壮性,值得收藏。

BreakNexus的博客 333

ValueTuple 相等性陷阱与最佳实践(90%开发者忽略的关键细节)

揭秘ValueTuple相等性常见误区,掌握高性能比较技巧。适用于集合查找、缓存键比对等场景,详解结构化相等与自定义比较器的正确用法,避免隐蔽bug。提升代码可靠性与执行效率,值得收藏。

PixelStream的博客 302

C#委托(Delegate)核心原理与高级应用实战

委托(Delegate)是C#实现函数式编程的核心机制,本质上是类型安全的函数指针。其核心原理在于通过方法签名绑定实现间接调用,支持多播能力与线程安全操作。在技术价值层面,委托大幅提升了代码的灵活性与可扩展性,特别是在事件处理、回调机制和LINQ查询等场景中表现突出。随着C#版本演进,泛型委托(Func/Action)、本地函数、函数指针等特性不断丰富委托生态。工程实践中需注意闭包捕获、内存泄漏等常见陷阱,在日志系统、游戏开发、金融引擎等实际业务场景中,委托能有效实现模块解耦与功能组合。掌握委托的多播特性、

weixin_33691700的博客 494

C#开发心得

IR(中间语言)等价于java的字节码。CLR(公共语言运行时)等价于JVM,用来执行IR。运行在.NET上的C#/F#/VB.NET/IronPython等语言都可以编译为IR,彼此互操作,就像JVM上kotlin/scala通过字节码与java语言互操作类似。

tlxamulet的博客 558

unity常见面试题

接口是一种完全抽象的类型,它只定义了成员的签名,但没有提供成员的实现。接口定义了对象应该具有的方法、属性和事件。抽象类是一种包含了抽象成员(方法、属性、索引器、事件)的类,它可以包含抽象成员和非抽象成员的实现。抽象类可以包含方法的实现,也可以包含字段和构造函数等。

yasin的博客 1万+
上一篇: C#泛型编程瓶颈突破:new()约束在依赖注入中的关键作用(案例实录)
下一篇: 【C#高级特性必知】:自动属性支持字段的5个关键事实
ProceChat
博客等级 码龄1年 155粉丝 1997原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值