.NET 下 TLS1.2引起的一场风波 C#

.NET 下 TLS1.2引起的一场风波

起因: 之前拿到过别人开发的一套采集程序源代码,几年前也自己改过部分代码,用着都还好。最近有一个新的业务需求,感觉那套程序比较适合,想拿来再改改。 (more…)
阅读全文
C#设计模式(1)——单例模式 [转] C#

C#设计模式(1)——单例模式 [转]

一、引言 最近在学设计模式的一些内容,主要的参考书籍是《Head First 设计模式》,同时在学习过程中也查看了很多博客园中关于设计模式的一些文章的,在这里记录下我的一些学习笔记,一是为了帮助我更深入地理解设计模式,二同时可以给一些初学设计模式的朋友一些参考。首先我介绍的是设计模式中比较简单的一个模式——单例模式(因为这里只牵涉到一个类) 二、单例模式的介绍 说到单例模式,大家第一反应应该就是——什么是单例模式?,从“单例”字面意思上理解为——一个类只有一个实例,所以单例模式也就是保证一个类只有一个实例的一种实现方法罢了(设计模式其实就是帮助我们解决实际开发过程中的方法, 该方法是为了降低对象之间的耦合度,然而解决方法有很多种,所以前人就总结了一些常用的解决方法为书籍,从而把这本书就称为设计模式),下面给出单例模式的一个官方定义:确保一个类只有一个实例,并提供一个全局访问点。为了帮助大家更好地理解单例模式,大家可以结合下面的类图来进行理解,以及后面也会剖析单例模式的实现思路: 三、为什么会有单例模式 看完单例模式的介绍,自然大家都会有这样一个疑问——为什么要有单例模式的?它在什么情况下使用的?从单例模式的定义中我们可以看出——单例模式的 使用自然是当我们的系统中某个对象只需要一个实例的情况,例如:操作系统中只能有一个任务管理器,操作文件时,同一时间内只允许一个实例对其操作等,既然 现实生活中有这样的应用场景,自然在软件设计领域必须有这样的解决方案了(因为软件设计也是现实生活中的抽象),所以也就有了单例模式了。 四、剖析单例模式的实现思路 了解完了一些关于单例模式的基本概念之后,下面就为大家剖析单例模式的实现思路的,因为在我自己学习单例模式的时候,咋一看单例模式的实现代码确实 很简单,也很容易看懂,但是我还是觉得它很陌生(这个可能是看的少的,或者自己在写代码中也用的少的缘故),而且心里总会这样一个疑问——为什么前人会这 样去实现单例模式的呢?他们是如何思考的呢?后面经过自己的琢磨也就慢慢理清楚单例模式的实现思路了,并且此时也不再觉得单例模式模式的,下面就分享我的 一个剖析过程的: 我们从单例模式的概念(确保一个类只有一个实例,并提供一个访问它的全局访问点)入手,可以把概念进行拆分为两部分:(1)确保一个类只有一个实例;(2)提供一个访问它的全局访问点;下面通过采用两人对话的方式来帮助大家更快掌握分析思路: 菜鸟:怎样确保一个类只有一个实例了? 老鸟:那就让我帮你分析下,你创建类的实例会想到用什么方式来创建的呢? 新手:用new关键字啊,只要new下就创建了该类的一个实例了,之后就可以使用该类的一些属性和实例方法了 老鸟:那你想过为什么可以使用new关键字来创建类的实例吗? 菜鸟:这个还有条件的吗?………, 哦,我想起来了,如果类定义私有的构造函数就不能在外界通过new创建实例了(注:有些初学者就会问,有时候我并没有在类中定义构造函数为什么也可以使用 new来创建对象,那是因为编译器在背后做了手脚了,当编译器看到我们类中没有定义构造函数,此时编译器会帮我们生成一个公有的无参构造函数) 老鸟:不错,回答的很对,这样你的疑惑就得到解答了啊 菜鸟:那我要在哪里创建类的实例了? 老鸟:你傻啊,当然是在类里面创建了(注:这样定义私有构造函数就是上面的一个思考过程的,要创建实例,自然就要有一个变量来保存该实例把,所以就有了私有变量的声明,但是实现中是定义静态私有变量,朋友们有没有想过——这里为什么定义为静态的呢?对于这个疑问的解释为:每个线程都有自己的线程栈,定义为静态主要是为了在多线程确保类有一个实例) 菜鸟:哦,现在完全明白了,但是我还有另一个疑问——现在类实例创建在类内部,那外界如何获得该的一个实例来使用它了? 老鸟:这个,你可以定义一个公有方法或者属性来把该类的实例公开出去了(注:这样就有了公有方法的定义了,该方法就是提供方法问类的全局访问点) 通过上面的分析,相信大家也就很容易写出单例模式的实现代码了,下面就看看具体的实现代码(看完之后你会惊讶道:真是这样的!): /// /// 单例模式的实现 /// public class Singleton { // 定义一个静态变量来保存类的实例 private static Singleton uniqueInstance; // 定义私有构造函数,使外界不能创建该类实例 private Singleton() { } /// /// 定义公有方法提供一个全局访问点,同时你也可以定义公有属性来提供全局访问点 /// /// public static Singleton GetInstance() { // 如果类的实例不存在则创建,否则直接返回 if (uniqueInstance == null) { uniqueInstance = new Singleton(); } return uniqueInstance; } } 上面的单例模式的实现在单线程下确实是完美的,然而在多线程的情况下会得到多个Singleton实例,因为在两个线程同时运行 GetInstance方法时,此时两个线程判断(uniqueInstance ==null)这个条件时都返回真,此时两个线程就都会创建Singleton的实例,这样就违背了我们单例模式初衷了,既然上面的实现会运行多个线程执 行,那我们对于多线程的解决方案自然就是使GetInstance方法在同一时间只运行一个线程运行就好了,也就是我们线程同步的问题了,具体的解决多线程的代码如下: /// /// 单例模式的实现 /// public class Singleton { // 定义一个静态变量来保存类的实例 private static Singleton uniqueInstance; // 定义一个标识确保线程同步 private static readonly object...
阅读全文
正则表达式之捕获组/非捕获组 -C# C#

正则表达式之捕获组/非捕获组 -C#

捕获组       语法: 字符  描述 示例 (pattern) 匹配pattern并捕获结果,自动设置组号。  (abc)+d 匹配abcd或者abcabcd (?<name>pattern) 或 (?'name'pattern) 匹配pattern并捕获结果,设置name为组名。 num 对捕获组的反向引用。其中 num 是一个正整数。 (w)(w)21 匹配abba k< name > 或 k' name ' 对命名捕获组的反向引用。其中 name 是捕获组名。 (?<group>w)abck<group> 匹配xabcx       使用小括号指定一个子表达式后,匹配这个子表达式的文本(也就是此分组捕获的内容)可以在表达式或其它程序中作进一步的处理。默认情况下,每个捕获组会自 动拥有一个组号,规则是:从左向右,以分组的左括号为标志,第一个出现的分组的组号为1,第二个为2,以此类推。       例如: (d{4}  )-(d{2}-  (d{2}   )  ) 1        1 2          3         3 2         以下是用程序处理捕获组的示例,对一个Url地址进行解析,并显示所有捕获组。       可以看到按顺序设置的捕获组号。 Regex.Match方法 using System.Text.RegularExpressions; namespace Wuhong.Test { class Program { static void Main(string[] args) { //目标字符串 string source = "http://reg-test-server:8080/download/file1.html# "; //正则式 string regex = @"(w+)://([^/:]+)(:d+)?([^# :]*)"; Regex regUrl = new Regex(regex); //匹配正则表达式 Match m = regUrl.Match(source); Console.WriteLine(m.Success); if (m.Success) { //捕获组存放在Match.Groups集合中,索引值从1开始,索引0处为匹配的整个字符串值 //按“组号 : 捕获内容”的格式显示 for (int i...
阅读全文
正则表达式-基础(C#) C#

正则表达式-基础(C#)

(1)“@”符号 “@”虽然并非C#正则表达式的“成员”,但是它经常与C#正则表达式出双入对。“@”表示,跟在它后面的字符串是个“逐字字符串”,不是很好理解,举个例子,以下两个声明是等效的: string x="D:\My Huang\My Doc"; string y = @"D:My HuangMy Doc"; 事实上,如果按如下声明,C#将会报错,因为“”在C#中用于实现转义,如“n”换行: string x = "D:My HuangMy Doc"; (2)基本的语法字符。 d 0-9的数字 D d的补集(以所以字符为全集,下同),即所有非数字的字符 w 单词字符,指大小写字母、0-9的数字、下划线 W w的补集 s 空白字符,包括换行符n、回车符r、制表符t、垂直制表符v、换页符f S s的补集 . 除换行符n外的任意字符 […] 匹配[]内所列出的所有字符 [^…] 匹配非[]内所列出的字符 下面提供一些简单的示例: string i = "n"; string m = "3"; Regex r = new Regex(@"D"); //同Regex r = new Regex("\D"); //r.IsMatch(i)结果:true //r.IsMatch(m)结果:false string i = "%"; string m = "3"; Regex r = new Regex("[a-z0-9]"); //匹配小写字母或数字字符 //r.IsMatch(i)结果:false //r.IsMatch(m)结果:true (3)定位字符 “定位字符”所代表的是一个虚的字符,它代表一个位置,你也可以直观地认为“定位字符”所代表的是某个字符与字符间的那个微小间隙。 ^ 表示其后的字符必须位于字符串的开始处 $ 表示其前面的字符必须位于字符串的结束处 b 匹配一个单词的边界 B 匹配一个非单词的边界 另外,还包括:A 前面的字符必须位于字符处的开始处,z 前面的字符必须位于字符串的结束处,Z 前面的字符必须位于字符串的结束处,或者位于换行符前 下面提供一些简单的示例: string i = "Live for nothing,die for something"; Regex r1...
阅读全文