《老生常谈:值类型 V.S. 引用类型》中花了很大的篇幅介绍ref参数针对值类型和引用类型变量的传递。在C#中,除了方法的ref参数,我们还有很多使用ref关键字传递引用/地址的场景,本篇文章作一个简单的总结。
现在直播平台由于弹幕的存在,主播与观众可以更轻松地进行互动,非常受年轻群众的欢迎。斗鱼TV就是一款非常流行的直播平台,弹幕更是非常火爆。看到有不少主播接入 弹幕语音播报器、 弹幕点歌等模块,这都需要首先连接斗鱼弹幕。
AOP的本质是方法拦截(将针对目标方法调用劫持下来,进而执行执行的操作),置于方法拦截的实现方案,不外乎两种代码注入类型,即编译时的静态注入和运行时的动态注入,本篇文章列出了几种常用的动态注入方案。
实际上,为了避免二叉树形状向最坏情况靠拢, 通常会创建能够自平衡的 2-3 树。 而 红黑树 是 2-3 树比较简单的一种实现形式:
我们都知道CPU和内存是程序最为重要的两类指标,那么有多少人真正想过这个问题:一个类型(值类型或者引用类型)的实例在内存中究竟占多少字节?我们很多人都回答不上来。其实C#提供了一些用于计算大小的操作符和API,但是它们都不能完全解决我刚才提出的问题。本文提供了一种计算值类型和引用类型实例所占内存字节数量的方法。源代码从这里下载。
我们都知道CPU和内存是程序最为重要的两类指标,那么有多少人真正想过这个问题:一个类型(值类型或者引用类型)的实例在内存中究竟占多少字节?我们很多人都回答不上来。
C#具有一个默认开启的代码分析规则:[CA1810]Initialize reference type static fields inline,推荐我们以内联的方式初始化静态字段,而不是将初始化放在静态构造函数中。
我在面试的时候经常会问一个问题:“谈谈值类型和引用的区别”。对于这个问题,绝大部分人都只会给我两个简洁的答案:“值类型分配在栈中,引用类型分配在堆中”,“在默认情况下,值类型参数传值(拷贝),引用类型参数传引用”。其实这个问题有很大的发挥空间,如果能够从内存布局、GC、互操作、跨AppDomain传递等方面展开,相信会加分不少。这篇文章独辟蹊径,从“变量”的角度讨论值类型和引用类型的区别。
本文列举了 15 个值得了解的 C# 特性,旨在让 .NET 开发人员更好的使用 C# 语言进行开发工作。 1. ObsoleteAttribute ObsoleteAttribute 适用于除组件、模块、参数和返回值以外的所有程序元素。将元素标记为 obsolete,可以通知用户该元素将在未来的版本中删除。 IsError - 设置为 true,编译器将在代码中使用这个属性时,提示错误。 public static class ObsoleteExample { // Mark OrderDet
HostingEnvironment是承载应用当前执行环境的描述,它是对所有实现了IHostingEnvironment接口的所有类型以及对应对象的统称。如下面的代码片段所示,一个HostingEnvironment对象承载的执行环境的描述信息体现在定义这个接口的6个属性上。ApplicationName和EnvironmentName分别代表当前应用的名称和执行环境的名称。WebRootPath和ContentRootPath是指向两个根目录的路径,前者指向的目录用于存放可供外界通过HTTP请求访问的资源
Event Bus(事件总线)是一种用于在应用程序内部或跨应用程序组件之间进行事件通信的机制。
样例中的扫雷实现主要是两个类型(BombGame 和 BombGrid),下面是完整代码:
目录 1. ObsoleteAttribute 2. 设置默认值属性: DefaultValueAttribute 3. DebuggerBrowsableAttribute 4. ??运算符 5. Curry 及 Partial 方法 6. WeakReference 7. Lazy 8. BigInteger 9. 非官方关键字:__arglist __reftype __makeref __refvalue 10. Environment.NewLine 11. ExceptionDispatch
本文来告诉大家,在 OpenXML 的 BodyProperties 的 NormalAutoFit 的 FontScale 属性缩放文本框的文本字号的方法
构成HostBuilderContext上下文的两个核心对象(表示配置的IConfiguration对象和表示承载环境的IHostEnvironment对象)可以直接注入Startup构造函数中进行消费。由于ASP.NET Core应用中的承载环境通过IWebHostEnvironment接口表示,IWebHostEnvironment接口派生于IHostEnvironment接口,所以也可以通过注入IWebHostEnvironment对象的方式得到当前承载环境相关的信息。
我们倾向于将IConfiguration对象转换成一个具体的对象,以面向对象的方式来使用配置,我们将这个转换过程称为配置绑定。除了将配置树叶子节点配置节的绑定为某种标量对象外,我们还可以直接将一个配置节绑定为一个具有对应结构的符合对象。除此之外,配置绑定还支持针对数据、集合和字典类型的绑定。(本篇提供的实例已经汇总到《ASP.NET Core 6框架揭秘-实例演示版》)
最近在阅读 .NET Core Runtime 的源码,参考大佬的代码,学习编写技巧和提高代码水平。学习过程中将学习心得和值得应用到项目中的代码片段记录下来,供日后查阅。
上文说到Unmanaged、BufferedBinary和BufferedString是NativeBuffering支持的三个基本数据类型,其实我们也可以说NativeBuffering只支持Unmanaged和IReadOnlyBufferedObject<T>两种类型,BufferedString、NativeBuffering和通过Source Generator生成的BufferedMessage类型,以及下面介绍的几种集合和字典类型,都实现了IReadOnlyBufferedObject<T>接口。
表达式树是 .net 中一系列非常好用的类型。在一些场景中使用表达式树可以获得更好的性能和更佳的扩展性。本篇我们将通过构建一个 “模型验证器” 来理解和应用表达式树在构建动态调用方面的优势。
在 Office 中,可以在 PPT 里面插入表格,插入表格有好多不同的方法,对应 OpenXML 文档存储的更多不同的方式。本文来介绍如何读取 PPT 内嵌 xlsx 格式的表格的方法
(1) 栗子1重新new赋值难道不是修改了原字典对象newDict吗?foreach字典为什么不报InvalidOperation异常?
与服务注册一样,针对配置的设置同样可以采用三种不同的编程模式。第一种是利用WebApplicationBuilder的Host属性返回的IHostBuilder对象,它可以帮助我们设置面向宿主和应用的配置。IWebHostBuilder接口上面同样提供了一系列用来对配置进行设置的方法,我们可以将这些方法应用到WebApplicationBuilder的WebHost属性返回的IWebHostBuilder对象上。不过还是那句话,既然推荐使用Mininal API,最好还是采用最新的编程方式。(本篇提供的实例已经汇总到《ASP.NET Core 6框架揭秘-实例演示版》)
上一章介绍了经过路由的处理,一个请求找到了具体处理这个请求的EndPoint,并最终执行它的RequestDelegate方法来处理这个Httpcontext。本章继续这个处理进程,按照惯例,依然通过几幅图来聊一聊这个RequestDelegate之后的故事。在此就避免不了的聊到各种Filter,它方便我们在action执行的前后做一些 “小动作”。(ASP.NET Core 系列目录)
本文是使用 WPF 做个 PowerPoint 系列的博客,本文来告诉大家如何解析 PPT 里面的文本描边效果,在 WPF 应用中绘制出来,实现像素级相同
《服务注册》、《服务消费》和《生命周期》主要从实现原理的角度对.NET Core的依赖注入框架进行了介绍,接下来更进一步,看看该框架的总体设计和实现。在过去的多个版本更迭过程中,依赖注入框架的底层实现一直都在发生改变,加上底层的涉及的大都是内容接口和类型,所以我们不打算涉及太过细节的层面。
接触到一个老的项目,里面大量使用OleDbConnection进行数据库操作,在执行SQL块语句时,对它的顺序参数、命名参数很不了解。据说不能使用命名参数,但我这里试验了一下,好像是可以的,只是对参数的顺序还是有要求。看看你能知道下面的输出结果吗?
之前一个项目涉及到针对海量(千万级)实时变化数据的计算,由于对性能要求非常高,我们不得不将参与计算的数据存放到内存中,并通过检测数据存储的变化实时更新内存的数据。存量的数据几乎耗用了上百G的内存,再加上它们在每个时刻都在不断地变化,所以每时每刻都无数的对象被创建出来(添加+修改),同时无数现有的对象被“废弃”(删除+修改)。这种情况针对GC的压力可想而知,所以每当进行一次2代GC的时候,计算的耗时总会出现“抖动”。为了解决这类问题,几天前尝试着创建了一个名为NativeBuffering的框架。目前这个框架远未成熟,而且是一种“时间换空间”的解决方案,虽然彻底解决了内存分配的问题,但是以牺牲数据读取性能为代价的。这篇文章只是简单介绍一下NativeBuffering的设计原理和用法,并顺便收集一下大家的建议。[本文演示源代码从这里下载]
虽然应用程序可以直接利用通过IConfigurationBuilder对象创建的IConfiguration对象来提取配置数据,但是我们更倾向于将其转换成一个POCO对象,以面向对象的方式来使用配置,我们将这个转换过程称为配置绑定。配置绑定可以通过如下几个针对IConfiguration的扩展方法来实现,这些扩展方法都定义在NuGet包“Microsoft.Extensions.Configuration.Binder”中。
AOP的本质是方法拦截(将针对目标方法调用劫持下来,进而执行执行的操作),置于方法拦截的实现方案,不外乎两种代码注入类型,即编译时的静态注入和运行时的动态注入,本篇文章列出了几种常用的动态注入方案。这篇文章的目标并不是提供完整的AOP框架的解决方案,而是说明各种解决方案后面的原理,所以我们提供的实例代码会尽可能简单。为了确定拦截操作是否执行,我们定义了如下这个Indicator类型,我们的拦截操作会将其静态属性Injected属性设置为True,我们演示的代码最终通过这个属性来确定拦截是否成功。[源代码从这里下载]
我写了一个特殊的控件,我期望了解到有哪些 VisualBrush 捕获了此控件,或者说有哪些 VisualBrush 用了此控件的界面
在对ASP.NET Core管道中关于依赖注入的两个核心对象(ServiceCollection和ServiceProvider)有了足够的认识之后,我们将关注的目光转移到编程层面。在ASP.NET Core应用中基于依赖注入的编程主要涉及到两个方面,它们分别是将服务注册到ServiceCollection中,和采用注入的方式利用ServiceProvider提供我们所需的服务。我们先来讨论ASP.NET Core应用中如何进行服务注册。[本文已经同步到《ASP.NET Core框架揭秘》之中] 目录 一
.NET利用ArrayPoolPool<T>和MemoryPool<T>提供了针对Array/Memory<T>的对象池功能。最近在一个项目中需要使用到针对字节数组的对象池,由于这些池化的字节数组相当庞大,我希望将它们分配到POH上以降低GC的压力。由于ArrayPoolPool<T>没法提供支持,所以我提供了一个极简的实现。
我们再简单回顾一下数组对象的内存布局。如下图所示,对于32位(x86)系统,Object Header和TypeHandle各占据4个字节;但是对于64位(x64)来说,存储方法表指针的TypeHandle自然扩展到8个字节,但是Object Header依然是4个字节,为了确保TypeHandle基于8字节的内存对齐,所以会前置4个字节的“留白(Padding)”。
在 OpenXML 的颜色画刷填充,有特殊的填充是 GrpFill 属性,对应 OpenXML SDK 定义的 DocumentFormat.OpenXml.Drawing.GroupFill 类型
由于Options模型涉及的核心对象最终都注册为相应的服务,所以从原则上讲这些对象都是可以定制的,下面提供几个这样的实例。由于Options模型提供了针对配置系统的集成,所以可以采用配置文件的形式来提供原始的Options数据,可以直接采用反序列化的方式将配置文件的内容转换成Options对象。
ASP.NET Core应用中的路由机制实现在RouterMiddleware中间件中,它的目的在于通过路由解析为请求找到一个匹配的处理器,同时将请求携带的数据以路由参数的形式解析出来供后续请求处理流程使用。但是具体的路由解析功能其实并没有直接实现在RouterMiddleware中间件中,而是由一个Router对象来完成的。[本文已经同步到《ASP.NET Core框架揭秘》之中] 目录 一、IRouter接口 二、RouteContext 三、RouteData 四、Route 五、RouteHan
ASP.NET Core应用中的路由机制实现在RouterMiddleware中间件中,它的目的在于通过路由解析为请求找到一个匹配的处理器,同时将请求携带的数据以路由参数的形式解析出来供后续请求处理流程使用。但是具体的路由解析功能其实并没有直接实现在RouterMiddleware中间件中,而是由一个Router对象来完成的。
一个对象总是映射一块连续的内存序列(不考虑对象之间的引用关系),如果我们知道了引用类型实例的内存布局,以及变量引用指向的确切的地址,我们不仅可以采用纯“二进制”的方式在内存“绘制”一个指定引用类型的实例,还能直接通过改变二进制内容来更新实例的状态。
在.NET 6中,微软加入了JSON Node,可以让我们动态编辑一个JSON文档,就像Newtonsoft.Json里的JToken一样,我们就可以更加灵活的操作JSON文档。 这次主要新增的API如下表:
如今的应用部署逐渐向微服务化发展,导致一个完整的事务往往会跨越很多的应用或服务,出于分布式链路跟踪的需要,我们往往将从上游服务获得的跟踪请求报头无脑地向下游服务进行转发。本文介绍的这个名为HeaderForwarder的组件可以帮助我们完成针对指定HTTP请求报头的自动转发。本篇文章分为上下两篇,上篇通过三个例子介绍HeaderForwarder的应用场景,下篇则介绍该组件的设计与实现。[源代码从这里下载]
通过《利用容器提供服务》我们知道作为依赖注入容器的IServiceProvider对象是通过调用IServiceCollection接口的扩展方法BuildServiceProvider创建的,IServiceCollection对象是一个存放服务注册信息的集合。在《一个迷你版DI框架》中创建的Cat框架中的服务注册是通过类型ServiceRegistry表示的,在.NET Core依赖注入框架中,与之对应的类型是ServiceDescriptor。
包含服务注册信息的IServiceCollection对象最终被用来创建作为DI容器的IServiceProvider对象。服务注册就是创建出现相应的ServiceDescriptor对象并将其添加到指定IServiceCollection集合对象中的过程。
在《读取配置数据》([上篇],[下篇])上面一节中,我们通过实例的方式演示了几种典型的配置读取方式,接下来我们从设计的维度来重写认识配置模型。配置的编程模型涉及到三个核心对象,分别通过三个对应的接口(IConfiguration、IConfigurationSource和IConfigurationBuilder)来表示。如果从设计层面来审视背后的配置模型,还缺少另一个名通过IConfigurationProvider接口表示的核心对象。总的来说,配置模型由这四个核心对象组成,但是要彻底了解这四个核心对象之间的关系,我们先得来聊聊配置的几种数据结构。
微软支持并发的Key-Value 存储库有C++与C#两个版本。号称迄今为止最快的并发键值存储。下面是C#版本翻译:
为了帮助大家更深刻地认识Dora.Interception,并更好地将它应用到你的项目中,我们通过如下几个简单的实例来演示几个常见的AOP应用在Dora.Interception下的实现。对于下面演示的实例,它们仅仅是具有指导性质的应用,所以我会尽可能地简化,如果大家需要将相应的应用场景移植到具体的项目开发中,需要做更多的优化。源代码从这里下载。 目录 一、对输入参数的格式化 二、对参数的自动化验证 三、对方法的返回值进行自动缓存 一、对输入参数的格式化 我们有一些方法对输入参数在格式上由一些要求,但是我们
近1年,偶尔发生应用系统启动时某些操作超时的问题,特别在使用4核心Surface以后。笔记本和台式机比较少遇到,服务器则基本上没有遇到过。
VBA写的再熟练的人,一般也很难做到一次性就写出完美无错的代码,总会有一些考虑不周全的情况或者单词写错而导致的程序出错,特别是新手,出错的可能就更加的高了。
在 OpenXML 的 PPT 的文本的字体是一个比较复杂的概念,即使在 OpenXML SDK 的辅助下,也需要自己写很多的逻辑。通过 ECMA 376 文档里面散落在各地的描述,和 dotnetCampus.OfficeDocumentZipper 工具的实验帮助之下,我摸到了本文将要告诉大家的规则,以及逻辑的实现
本文是我在读 WPF 源代码做的笔记。在 WPF 中的 AppDomainShutdownMonitor 类是一个不开放的类,这个类当前只是给 D3DImage 类使用。在 AppDomainShutdownMonitor 提供了在应用的进程或程序域关闭的时候,进行一次通知,当前是用来清理 D3DImage 类的资源
领取专属 10元无门槛券
手把手带您无忧上云