IT技术博客大学习 共学习 共进步
全部 移动开发 后端 数据库 AI 算法 安全 DevOps 前端 设计 开发者

标签:C#

共 17 篇相关文章

IT 累计浏览 46

深远未来开发总结

本文是一位独立开发者对《深远未来》桌游数字化项目的开发总结。作者从兴趣出发,旨在实践中探索游戏开发难题。整个开发历时约七周,期间穿插搬家等意外,但通过清晰的流程规划和对开发情绪的重视,最终完成了游戏的第一个可玩版本。 技术层面,作者基于自研引擎soluna进行开发,初期为提升效率选择了结构化文本描述界面而非图形编辑器。在将游戏规则转化为数字交互的过程中,面临诸多挑战:例如如何将桌游中自然的、多线程的玩家决策(如advancement效果结算)转化为合理的数字版交互流程,同时又不丢失原版的游戏感和规则深度;如何设计底层的提示与状态机系统以管理复杂的游戏流程;以及如何处理后期的胜利结算、存档、文明卡等复杂功能模块的实现与重构。 作者反复强调保持开发热情的重要性,通过按游戏流程次序逐步实现功能、保持每日进度、及时提供视觉反馈等方式来维持动力。同时,他也认识到过早追求快速实现会导致代码冗余,因此将“尽早且频繁的重构”作为关键经验。开发后期,通过开源吸引了程序员参与合作,共同完善了跨平台支持和本地化,验证了协作对独立项目的增益。 最终,项目代码量控制在约两万行。作者总结,控制代码规模需做好数据与引擎分离,而记录并适时优化代码结构比性能优化更为优先。这次经历让他坚信,明确的任务拆分、对开发情绪的管理以及对代码所有权的重视,是独立游戏开发成功的关键。

IT 累计浏览 2,011

阅读.NET源代码那些事

这篇讲的是如何通过直接阅读.NET框架源代码,来深入理解其内部实现机制。作者以自己在项目“Tmc”中借鉴BCL代码的经历为例,指出虽然.NET大部分组件不开源,但微软已公开了参考源代码库,并保持与版本的同步更新。 文章重点对比了反编译工具(如.NET Reflector)与直接阅读源代码的差异。作者指出,反编译会丢失变量名、注释等关键信息,而源代码中保留的详细注释,例如Hashtable实现中关于哈希算法选择的说明,更能清晰揭示设计思路和实现背景。 作者还通过Dictionary类的代码实例,揭示了一个巧妙的实现细节:在特定编译条件下,当插入操作的哈希碰撞次数超过阈值,Dictionary会随机化其比较器。这一机制正是为了应对曾引发安全关注的哈希碰撞DoS攻击,展现了框架在安全与性能上的权衡。 最终,作者将这些源于阅读源代码的经验应用到自己的项目中,通过参考和修改BCL代码来构建自定义的HashDictionary,证明了这种方法在提升代码质量与理解深度上的直接价值。

IT 累计浏览 2,193

C#的设计缺陷(2):不能以void作为泛型参数

这篇文章从C#与Java泛型的对比切入,探讨了C#作为“真泛型”语言在语言设计层面的另一项限制:不允许将void作为泛型类型参数。作者指出,.NET的真泛型本是一大优势,但具体到C#编译器的实现与运行时约束,却衍生出这一设计缺口。 文章并未深入剖析其技术成因,而是将C#视为一个既成“产品”,着重分析了这一限制所带来的实际编程后果。它揭示了在试图用泛型统一处理值类型与引用类型(包括表示“无返回值”的void)时,开发者可能遇到的设计困境与代码冗余。 对于关注语言设计权衡与.NET生态实际特性的开发者而言,这提供了一个理解C#泛型边界与当前编程模型局限性的具体案例。

IT 累计浏览 2,377

C#的设计缺陷(1):显式实现接口内的事件

这篇讲的是C#语言里一个长期存在的“遗憾设计”:当我们试图在一个类中显式实现接口定义的事件时,编译器会强制要求我们手动提供add和remove访问器的完整实现。 这打破了C#事件最常用的、便捷的`event`自动实现模式。作者从自己多年的编码体验出发,指出这种限制虽然无伤大雅,却显得多余,因为它并没有带来任何实质性的安全或功能增益,反而徒增了繁琐的样板代码。这种“细枝末节”的设计决策,也侧面反映了语言在演进过程中,某些早期设定可能成为后续难以改变的“路径依赖”。

IT 累计浏览 5,242

为什么国内还有那么多网站使用.NET架构?

这篇讲的是一个有趣的技术选型现象:在Node.js、Go、Java等技术席卷互联网的今天,为什么国内仍有不少知名网站选择坚守.NET架构?文章从具体案例切入,列举了包括电商、金融等领域在内的一批大型站点,并分析了它们共同的技术背景与历史沿革。 作者并未停留在表面的列举,而是深入探讨了几个核心原因:.NET框架本身成熟的工程化能力、与Windows生态深度集成的历史红利、以及Visual Studio等工具链带来的极高开发效率。文章特别指出,随着.NET Core的跨平台演进,一些团队开始利用其高性能特性重构关键服务,形成了一种“前端多技术栈、后端.NET核心化”的混合架构模式。 对比其他技术路线,作者认为.NET在国内的持续存在,既是技术路径依赖的体现,也反映了特定业务场景下对稳定性和开发效率的务实选择。对于正在做技术选型的团队来说,这篇文章提供的视角不是盲目追随潮流,而是从团队基因与业务需求出发进行冷静评估。

IT 累计浏览 2,916

匿名类型的硬伤:围绕this的成员捕获策略

这篇讲的是C#程序员常憧憬的Java式匿名类特性,但作者在深究Java语言规范后,却发现了其中围绕 `this` 的成员捕获策略存在难以回避的“硬伤”。这并非关乎设计品位,而是一个根本性的实现难题。 文章的核心对比在于,Java的匿名类(作为内部类的一种)在捕获外部成员时,必须隐式或显式地通过一个外部类引用来访问 `this`。这导致了代码意图与实际执行之间的微妙错位:你在匿名类里写的 `this` 指向的是匿名类自身,而要访问外部成员则需要借助外部类实例。相比之下,C#的lambda表达式捕获的是变量副本或引用,其行为更直接、一致。 作者从实际编码体验出发,剖析了这种差异带来的后果。Java的这种方式可能导致非预期的内存持有和更复杂的生命周期问题,使得某些场景下的代码既不直观也不安全。最终的结论颇具启发性:一个语言特性的引入,不能只看表面的便捷,其底层对核心概念(如 `this`)的处理方式,才决定了它是否是一个“干净”的设计。如果C#无法用更优雅的方式解决这个捕获策略,那么保持现状反而是更负责任的选择。

IT 累计浏览 3,838

什么是闭包(Closure)?

这篇讲的是一个在编程中既基础又容易让人困惑的概念——闭包。作者从词源“closure”出发,非常直观地解释了为什么叫这个名字:闭包就像把函数和它需要的一切“封装”在一个包里带走。 文章没有一开始就扔出复杂的定义,而是通过简单的代码示例,展示闭包如何“记住”并访问其词法作用域之外的变量。这解决了编程中一个关键问题:如何在函数执行结束后,依然能安全地访问或维护它所依赖的状态。比如在回调函数、模块化封装或需要缓存结果的场景中,闭包都提供了优雅的解决方案。 不同于枯燥的语法说明,这篇文章更侧重于讲清楚闭包“能做什么”以及“为什么这样设计”。读完后,你会明白它并非什么黑魔法,而是一种精心设计的机制,让函数具备了跨越时间维护状态的能力。通过这篇讲解,你会对“函数加上其引用的外部环境”这一精巧设计,有一个清晰的认知。

IT 累计浏览 2,760

匿名类型的硬伤:围绕this的成员捕获策略

这篇讲的是一个关于编程语言特性的深层观察。作者从C#程序员对Java匿名类特性的向往谈起,但随后话锋一转,带我们深入Java语言规范,揭示了其中关于`this`引用的一个根本性矛盾。 文章的核心观点犀利:Java匿名类(及内部类)中的`this`关键字,其作用域被“向外”指到了外部类的实例上,而非匿名类自身。这种设计会导致作用域混淆和意外的成员捕获行为,作者称之为难以避免的“硬伤”。相比之下,C#通过匿名类型与lambda表达式结合,其捕获局部变量形成闭包的策略则清晰得多,变量归属一目了然。 通过这个具体的`this`捕获问题,文章揭示了语言特性设计中一个重要的权衡:便捷性与可预测性之间的取舍。它让读者意识到,一些看似“缺失”的语法糖,背后可能隐藏着避免更深复杂性的深思熟虑。理解这一点,或许能让我们对所用语言的特性选择有更清醒的认识。

IT 累计浏览 3,922

设计模式速查手册-创建型

这篇讲的是创建型设计模式的一份“速查手册”,它的独特之处在于用 Is & Is Not 的对比框架来厘清每个模式的核心。作者没有从 UML 类图或复杂定义入手,而是直击要点:这个模式是什么,尤其强调它“不是什么”。比如,它区分了简单工厂、工厂方法与抽象工厂的适用边界,也点明了单例模式并非全局变量的代名词。这种清晰的对比能帮开发者在面对具体需求时,快速排除不合适的选项,找到最匹配的模式。文章把抽象的概念转化成了决策工具,让查阅过程变得更高效。

IT 累计浏览 2,673

程序设计中的计算复用(Computational Reuse)

这篇讲的是计算复用——一个通过“记住结果”来避免重复劳动的编程思想。作者从斐波那契数列这个经典例子切入,直观对比了三种计算方式:朴素递归的指数级时间复杂度,记忆化(Memoization)的显著提速,以及动态规划(Dynamic Programming)的自底向上最优解。 文章的核心并非仅仅讲解算法,而是以它为透镜,阐释“计算复用”这一更通用的模式。它清晰地指出,在计算资源有限的现实世界中,单纯追求代码的优雅或直观是不够的,我们必须有意识地在“用空间换时间”和“设计更优的计算路径”之间做出权衡。这种思想不仅适用于算法竞赛,更是优化任何有大量重复计算场景(如前端渲染、数据库查询)的关键。 最后,文章将计算复用与“抽象”和“设计模式”进行了有启发的类比。它告诉我们,优秀的程序员不仅是在写代码,更是在设计一个高效、可复用的“计算过程”。这种从具体代码上升到通用思想的视角,能帮助我们在面对复杂系统时,更主动地去寻找和设计其中的复用机会。

IT 累计浏览 2,453

PDC 2010:C#与Visual Basic的未来(下)

这篇讲的是C#之父Anders Hejlsberg在PDC 2010大会上,对.NET语言未来演进路径的一次重要擘画。演讲的核心聚焦于两项即将引入C#与Visual Basic的革命性特性:**异步编程**与**编译器即服务**。 作者从Anders的现场演示出发,重点剖析了异步编程如何通过引入`async`和`await`这两个简洁关键字,彻底革新了处理I/O密集型任务的编程模型。它使得开发者能以近乎同步代码的流畅逻辑,编写出高效、非阻塞的异步操作,极大提升了代码的可读性与可维护性。 另一部分则初步探触了“编译器即服务”这一更前沿的构想。它旨在将编译器的能力(如语法树、语义分析)作为一种服务开放出来,让开发者能够编写在编译期分析和操作代码的工具与扩展。这不仅是.NET生态中元编程的强大基础,也为代码分析、智能工具和领域特定语言(DSL)的创建打开了全新的大门。 Anders的分享清晰地勾勒出,未来语言设计不仅追求运行时性能与表达力,更致力于通过提升开发体验和赋予元编程能力,来应对软件复杂性不断增长的挑战。

IT 累计浏览 2,299

PDC 2010:C#与Visual Basic的未来(中)

这篇总结聚焦于PDC 2010上Anders Hejlsberg关于C#与Visual Basic未来方向的关键演讲,重点剖析了“异步”与“编译器即服务”两大特性。不同于逐句翻译,作者以Anders的视角,用简捷的方式重构了演讲的核心内容。 文章深入阐述了async和await这两个关键字背后的实现原理。它解释了编译器如何将异步代码转换为状态机,从而在保持代码简洁性的同时,避免了传统回调模式的复杂性,并显著提升了应用的响应性。对于“编译器即服务”,文章探讨了其如何将编译器能力开放给开发者,使得在运行时分析和生成代码成为可能,这为元编程和开发工具链带来了新的想象空间。 作者通过梳理Anders对这两项特性的设计哲学与技术细节,清晰地勾勒出未来语言演进将如何更深入地解决并发编程的复杂性,并拓展开发者的工具边界。对于想理解现代C#核心语言特性起源和设计思想的开发者来说,这篇复盘提供了扎实的技术洞察。

IT 累计浏览 3,049

PDC 2010:C#与Visual Basic的未来(上)

这篇讲的是PDC 2010大会上关于C#与Visual Basic未来发展方向的探讨。PDC作为微软的重要开发者会议,常常发布前沿技术信息,本文基于Anders Hejlsberg的演讲内容展开。文章详细分析了C#和

IT 累计浏览 4,433

C#和C++混合编程的一些tips

这篇来自实战的经验分享,讲的是作者在帮朋友开发时,如何将C#和C++这门“老将”与“新秀”结合起来用。文章没有停留在语法层面,而是直指混合编程中最实际的痛点——两种语言在内存管理、数据类型和调用方式上的天然隔阂。 作者具体提到了使用P/Invoke进行互操作时,如何小心处理字符串和结构体的内存布局,避免常见的崩溃问题。也分享了在涉及高性能计算模块时,如何将核心算法用C++实现,再通过COM接口或动态链接库的方式,让C#上层业务代码能够安全、高效地调用。这些具体的场景和解决方案,正是混合编程从理论走向实践时必须跨越的沟壑。 对于那些需要利用C#的快速开发和生态,又无法完全放弃C++底层性能或遗留库的团队来说,这些踩坑后的梳理,或许比一份完整的官方文档更接地气。

IT 累计浏览 3,303

C#网络通信中中文字符的传送以及SQL数据库存取中文的解决方法

这篇讲的是一个在C#网络编程和数据库操作中非常经典的“坑”:中文乱码。作者从Socket通信的场景切入,描述了一个常见现象——当直接发送包含中文的字符串时,接收端看到的往往是一堆毫无意义的乱码。其核心原因在于,默认的字符串处理方式没有正确统一编码格式。 文章详细拆解了问题的根源与解决方案。它指出,必须在数据发送前和接收后,明确统一地采用像UTF-8这样的通用编码进行字节转换。这个原则同样适用于操作SQL数据库存取中文数据的场景,即连接字符串中指定正确的字符集。作者不仅给出了具体的编码处理代码示例,还延伸讨论了在不同开发环节(如Socket通信、数据库连接、文件读写)中保持编码一致的重要性。 对于经常处理多语言数据或从事网络应用开发的程序员来说,这篇文章厘清了编码混乱这个隐蔽却频繁出现的问题,提供了从原理到实践的完整解决路径。掌握其中的方法,能有效避免后续开发中不必要的调试时间。

IT 累计浏览 5,654

.NET 还是 Java?

这篇文章以一段真实的校园对话为起点,一名大二计算机专业的学生向作者询问:为什么许多大型企业似乎更倾向于招聘Java程序员,而.NET的使用场景似乎相对受限?作者由此展开对.NET与Java的全面对比,深入分析了两种技术栈在核心差异、生态系统和适用场景上的不同。 文章指出,.

IT 累计浏览 4,216

通过HttpListener实现轻量级Web服务器[原创]

这篇讲的是作者在研读C#版BT协议实现MonoTorrent的源码时,从其Tracker模块里“挖”出一个实用亮点——基于HttpListener实现轻量级Web服务器。HttpListener是.NET框架自带的类,常被忽略,但它能快速搭建一个无需IIS等重型依赖的HTTP服务端,代码量极少,非常适合在本地服务、临时工具或测试环境里“救急”。 作者没有停留在理论层面,而是单独将这段逻辑提取出来,编写了测试代码并验证了其可用性。这个实践点出了它的核心价值:当你在做P2P通信、本地数据交互等场景,需要快速起一个简单的HTTP接口时,这比部署一个完整的Web服务器要灵活高效得多。文章用亲身经历说明,有时翻阅优秀项目的源码,除了学习架构,也能发现这种直接可用的“瑞士军刀”。