yangyang

a .NET Developer

All Posts


C#设计模式之装饰模式

假设我们要扩展同事编写的某个类的某些功能,怎样在不修改类的前提下,增加新的功能呢?有一种方法是使用继承,编写一个继承自该基类的子类,然后添加新的方法,或者重写父类里面的某些方法或属性。 问题在于,在有些情况下,并不能继承。最常见的是这个类无法继承,要么是我们编写的类,需要继承自其他类,而在C#里面,不允许多各类继承,再就是这类是封闭的Sealed,无法继承。 Decorator装饰模式,可以使得我们扩展已经存在的类,而不需要修改已经存在类的代码,并且避免了继承导致产生过多子类。下面用一个例子来说明装饰模式。 自定义字符串构造器 假设我们要做一个代码生成器的功能,需要扩展StringBuilder,来增加缩进功能。首先想到的是直接继承自StringBuilder类,但是出于安全原因,这个类是Sealed封闭类,另外,还要保存当前缩进的级别用来给方法 …

Design Pattern Decorator Pattern Dynamic Decorator Static Decorator Decorator Composition

C#设计模式之组合模式

一个对象通常包含(composed)其他对象,或者说聚合(aggregate)其他对象。有一些方法能够让一个对象能够包含其他对象。最简单的是,让这个对象实现IEnumerable<T>接口,或者包含某个实现了IEnumerable<T>对象的public字段。 另外一种方式是继承自一些集合类,比如Collection<T>、List<T>等。因为继承自集合对象,所以对象本身也拥有了相关的存储特性。 因此,什么是组合模式?简单来说是让单个对象跟集合对象一样,让他们拥有相同的接口以及接口对象,这使得我们在使用这些接口及对象时,不需要关心该对象是单个对象还是集合对象。为了说明组合模式,下面举几个例子: 例1:图形对象集合 我们用过PowerPoint,在做PPT的时候,我们有时候选择一个对象,有时候选择多 …

Design Pattern Composite Pattern

C#设计模式之单例模式

单例模式(Singleton),故名思议就是说在整个应用程序中,某一对象的实例只应该存在一个。比如,一个类加载数据库中的数据到内存中以提供只读数据,这就很适合使用单例模式,因为没有必要在内存中加载多份相同的数据,另外,有些情况下不允许内存中存在多分份相同的数据,比如数据过大,内存容不下两份相同数据等等。 约定单例模式(Singleton by Convention) 这种方式有点“Too simple, Sometimes naïve”,他就是提示使用者,我是单例,不要重复初始化我,比如: public class Database { /// <summary> /// 警告,这是单例,不要初始化多次,否则,后果自负. /// </summary> public …

Design Pattern Creational Patterns Singleton

C#设计模式之原型模式

Prototype模式为创建型模式,翻译为原型模式。这种模式在生活中随处可见,很多产品设计一般都不会从头开始,都是从上一个版本直接不停的迭代,比如手机界早前的诺基亚“科技以换壳为本”,以及汽车工业界的更新,一般是过一年一个小改版基本就是“facelift”,然后才是大换代。 在软件工程中亦是如此,在有些情况下,与其从头开始创建一个对象(比如工厂方法模式或者生成器模式做的那样),可以从之前预构造的对象或者直接拷贝原有对象,或者对原有对象简单修改来生成新的对象。 这就产生了原型模式的概念,通过对某个对象的拷贝,定制化从而得到新的对象,原型模式的核心是拷贝,这也是容易出现问题的地方。 深拷贝与浅拷贝 拷贝分为深拷贝(Deep copy)和浅拷贝(Shallow copy)之分,区分两者至关重要。下面来看例子,我们定 …

Design Pattern Prototype Pattern Deep Copy Shallow Copy Prototype Factory

C#设计模式之生成器模式

Builder模式是创建型模式,它用来构建比较复杂的对象,这些对象无法通过单一的构造函数来实现,比如要构造一个类似HTML这样的具有嵌套结构的对象,这个类或许由其他几个类或者对象构成,或者具有一些特殊的构建逻辑。 Builder这里翻译参照GoF翻译为生成器模式,通常用来建造复杂的对象,下面用几个例子来说明,这些例子只是用来说明生成器模式,在实际应用中还要考虑其他因素。 场景 假设我们需要构建一个组件用来显示web页面。一个Web页面可能包含一个或者多个段落,或者其他组件,要构建一个段落,通常可以简单用字符串拼接,比如下面这个代码就构建了一个p段落。 var hello = "hello"; var sb = new StringBuilder(); sb.Append("<p>"); sb.Append(hello); sb. …

Design Pattern Builder Pattern Creational Patterns

C#表达式树:用表达式树替代反射

在动态调用对象方法方面,可以使用重构。但是在速度方便,重构比直接调用方法要慢很多,这里有两篇文章Expression Tree vs reflection,Again on Expression Tree vs Reflection 对比了表达式树和重构,以及 用lambda表达式树替代反射 这篇文章,在一些场景下,我们可以直接使用表达式树来代替重构。 本文将以Fix框架源码来说明,在一些特定场景下使用表达式树来替代反射能达到的奇妙效果和优点。 什么是FIX协议 FIX(Financial Information eXchange)金融信息交换协议是一种主要用于证券交易过程交换的公开协议,它定义每条交易信息的内容和格式,这些信息内容与证券交易流程相对应,以保证交易信息安全准确地传送。FIX主要用于在各类参与者之间建立起实时的电子化通讯协议。 FIX协议 …

Lambda Expression Expression Trees Fix QuickFixn Reflection

C#表达式树:构建动态查询

前文介绍了C#中表达式树的基本知识,在实际中,表达式树有很多用法,这里举几个例子,说明如何使用表达式树构建动态查询,从而扩展LINQ的查询方法。 在LINQ中,只要数据源实现了IQuerable<T>接口,表达式树就可以用来表示结构化查询。比如,LINQ提供了用来查询关系数据源的IQueryable<T>接口的实现,C#编译器在执行这类数据源查询时,会在运行时生成表达式树,然后,查询会遍历表达式树的数据结构,然后将其转换成针对特定数据源的合适的查询语言。 下面的几个例子演示了如何使用表达式树动态生成查询。 Example 1:动态生成Where和OrderBy 这个例子是MSDN上的例子,平常在C#中我们一般直接写LINQ代码,比如下面这个: companies.Where(company => (company. …

Lambda Expression Expression Trees Build Dynamic Query Safe Databinding

C#表达式树:基本用法

表达式树使用一种类似树的结构来表示代码,它的每个节点都是一个表达式,比如方法调用和x<y这样的二元运算等。我们可以对表达式树的内容进行编辑和运算,这样能够动态修改可执行代码,以及动态创建查询等。我们可以使用匿名lambda表达式或者C# API来创建表达式树。 这一系列文章,主要是对C#表达式树的一种总结,基本知识参考MSDN的内容 这部分内容可以直接到MSDN上查看,后面的几篇文章主要分享一下,在工作中碰到的应用到表达式树的部分,谨做为记录和分享。 生成表达式树 通过lambda表达式创建表达式树 可以通过将lambda表达式赋值给Expression<TDelegate>类型的变量,编译器可以自动生成创建该lambda表达式的表达式树。C#编译器只能从lambda表达式生成表达式树,只能是单行lambda表达式,不能解析多行 …

Lambda Expression .NET Core Expression Trees

.NET Core IoT破解PS2通讯协议

之前使用315MHZ可以进行远程控制,但是那个只有4个按钮,理论上只能控制4个变量的输入,并且偶尔信号还会串,所以需要探索其他远程控制方式。 PS2是Sony PlayStation2游戏机的遥控手柄,它采用的是2.4G无线通讯技术,有效控制范围能达到10米。恰好有人已经破解了通讯协议,使得手柄能够接到其他器件上遥控使用,比如这个叙利亚战场上使用PS2手柄控制的遥控机枪,我们这里只是简单的用在智能小车上,当然可以扩展到很多需要控制的地方,他的特点是性价比非常高(只要几十块钱就能买到一套山寨的控制器和接口,正版Playstation 2是不可能这个价格的,但是功能一点不差),而且按键丰富,方便扩展。 PS2手柄介绍 PS2手柄和接收器如下图: ▲ PS2 手柄和接收器 手柄,主要用来发送按键信息,接收器与主机相连(主机可以是树莓派,也可以是 …

IoT .NET Core PS2Controller

ASP.NET Core SignalR入门(三):后台服务及Chrome插件

前文介绍了如何通过SignalR将捕获到的摄像头信息,通过Streaming的方式传输到客户端。在PiMonitor例子中,作者在后台通过SignalR后台服务的方式,隔一段时间获取图像帧,然后连接Azure的认知服务来判断Baby是否在哭,从而向客户端触发提醒,这里就用到了SignalR的后台服务以及涉及到了开发Chrome插件来作为SignalR的客户端,下面逐个介绍。 SignalR后台服务 要在后台长期运行,并且能够通过SignalR向客户端发送消息,就需要用到SignalR的后台服务(background service)。ASP.NET Core承载SignalR后台服务,跟承载SignalR的Hub相似。只需要在ConfigurationServices中AddSignalR以及AddHostedService中注册需要的后台服务类. public …

SignalR ASP.NET Core SignalR Real-time App Hub Chrome Extension Background services