一切福田,不離方寸,從心而覓,感無不通。

Category Archives: C#

简短介绍 C# 6 的新特性

几周前我在不同的地方读到了有关C#6的一些新特性。我就决定把它们都收集到一起,如果你还没有读过,就可以一次性把它们都过一遍。它们中的一些可能不会如预期那样神奇,但那也只是目前的更新。 你可以通过下载VS2014或者安装这里针对visual studio2013的Roslyn包来获取它们。 那么让我们看看吧: 1. $标识符 $的作用是简化字符串索引。它与C#中那些内部使用正则表达式匹配实现索引的动态特性不同。示例如下: ? 1 2 3 4 5 6 7 8 9 10 11 var col = new Dictionary<string, string>()             {                 $first = "Hassan"             };    //Assign value to member    //the old way:    col.$first = "Hassan";    //the new way:    col["first"] = "Hassan";   2. 异常过滤器 VB编译器中早已支持异常过滤器,现在C#也支持了。异常过滤器可以让开发人员针对某一条件创建一个catch块。只有当条件满足时catch块中的代码才会执行,这是我最喜欢的特性之一,示例如下: ? 1 2 3 4 5 try             {                 throw new Exception("Me");             }             catch (Exception ex) if (ex.Message == "You")   3. catch和finally块中await关键字 据我所知,没有人知道C# 5中catch和finally代码块内await关键字不可用的原因,无论何种写法它都是不可用的。这点很好因为开发人员经常想查看I/O操作日志,为了将捕捉到的异常信息记录到日志中,此时需要异步进行。 ? 1 2 3 4 5 6 7 8 try             {                 DoSomething();             }             catch (Exception)             {                 await LogService.LogAsync(ex);             } 4. 声明表达式 这个特性允许开发人员在表达式中定义一个变量。这点很简单但很实用。过去我用asp.net做了许多的网站,下面是我常用的代码: ? 1 2 3 long id; if (!long.TryParse(Request.QureyString["Id"], out id)) { } 优化后的代码: ? 1 2 if (!long.TryParse(Request.QureyString["Id"], out long id)) { } 这种声明方式中变量的作用域和C#使用一般方式声明变量的作用域是一样的。 5. Static的使用 这一特性允许你在一个using语句中指定一个特定的类型,此后这个类型的所有静态成员都能在后面的子句中使用了. ? 1 2 […]

龙生   20 Aug 2014
View Details

C# 权重控制随机抽取率

增加、减少随机抽中几率——此算法可用于题库随机抽题、赌博机控制出彩率,甚至俄罗斯方块等游戏,有广泛的用途!也希望能帮得到你! 强调      在随机的基础上增控制抽中几率,注意随机性!! 正文       一、文字解说:            为待随机抽取的集合每个项加一个权值,这个权值就是随机几率,比如正常被抽正的几率为1,那么将希望被抽中几率更大的项的权值设置为3或5,然后随机抽取集合中的项,并将随机数乘以每个项对应的权值,然后排序!!提取前N个项即可!大家可以发现权值更高被乘之后有更高几率排在前面而被抽中,如果将权值设为0将永远也不会被抽中!       二、应用场景:            1.      随机抽题:如果题A去年考过了,那么我希望今年出现的几率更小或者不出现,那么我将题A的权值设置为0,这道题将在以后的考试随机抽题中永远不会被随机抽中;而另外题B是本院今年模拟考试中的一道题目,我将这道题权值增加到5,根据算法,那么这道题目在下次随机抽题抽中率将比普通题目提高数倍!            2.      赌博机:大家知道游戏厅里面的赌博机是可以调的,被人调了之后出彩率明显提高或者降低,我觉得本算法适合解释。假设赌博机有24个赌项可供选择,分别是A-Z各个字母,按正常几率的话每个项的权值都是1,调机师可以通过动态改变权值来达到提高或降低中奖率。假如你投三个币,分别选了A、B、C,赌博机根据调机师的设置动态改变了A、B、C的权值,让灯转3-4圈后更大的几率停留在这三个选择中奖金较少的一个。            3.      俄罗斯方块:大家在打QQ俄罗斯方块对打的时候,有时候明显感觉堆得越高,出的东西反而不顺意,我觉得本算法也可以达到这个效果。计算机能算得出下一个最优方案是出条还是出角最好,所以可以通过调整权值来打破平均出现的几率来达到这个目的!       三、代码实现(C#实现):       RandomController.cs using System; using System.Collections.Generic; using System.Text; /* 为待随机抽取的集合每个项加一个权值,这个权值就是随机几率,比如正常被抽正的几率为1, 那么将希望被抽中几率更大的项的权值设置为3或5,然后随机抽取集合中的项,并将随机数 乘以每个项对应的权值,然后排序!!提取前N个项即可!大家可以发现权值更高被乘之后 有更高几率排在前面而被抽中,如果将权值设为0将永远也不会被抽中! */ namespace 随机抽奖 { public class RandomController { #region Properties private int _Count; /// <summary> /// 随机抽取个数 /// </summary> public int Count { get{return _Count;} set{_Count = value;} }         #endregion         #region Member Variables         /// <summary> /// 待随机抽取数据集合 /// </summary> public List<char> datas = new List<char>( new char[]{ 'A',’B',’C',’D',’E',’F', 'G',’H',’I',’J',’K',’L', 'M',’N',’O',’P',’Q',’R', 'S',’T',’U',’V',’W',’X', 'Y',’Z' […]

龙生   17 Jul 2014
View Details

C#集合类Queue

队列(Queue)在程序设计中扮演着重要的角色,因为它可以模拟队列的数据操作。例 如,排队买票就是一个队列操作,新来的人排在后面,先来的人排在前面,并且买票请求 先被处理。为了模拟队列的操作,Queue在ArrayList的基础上加入了以下限制: · 元素采用先入先出机制(FIFO,First In First Out),即先进入队列的元素必须先离 开队列。最先进入的元素称为队头元素。 · 元素只能被添加到队尾(称为入队),不允许在中间的某个位置插入。也就是说, 不支持ArrayList中的Insert方法。 · 只有队头的元素才能被删除(称为出队),不允许直接对队列中的非队头元素进行 删除,从而保证FIFO机制。也就是说,不支持ArrayList中的Remove方法。 · 不允许直接对队列中非队头元素进行访问。也就是说,不支持ArrayList中的索引访 问,只允许遍历访问。 下面的实例展示了如何创建Queue对象,并向Queue对象中入队数据、出队数据、遍历 数据。 创建TestQueue类,在TestQueue.cs中输入如下代码: using System; using System.Collections.Generic; using System.Text; using System.Collections; namespace Chapter12 { class TestQueue { static void Print(Queue list) { Console.Write("队列内容:"); foreach (string str in list) System.Console.Write(str + " "); } static void Main(string[] args) { Queue list = new Queue(); //Add elements Console.WriteLine("输入字符串添加到队列(#号结束):"); string str; do { str = Console.ReadLine(); if (str == "#") break; else { list.Enqueue(str); } } while (true); TestQueue.Print(list); Console.WriteLine(); //Remove elements Console.WriteLine("出队字符串:"); while (list.Count != 0) […]

龙生   30 Jun 2014
View Details

volatile(C# 参考)

volatile 关键字指示一个字段可以由多个同时执行的线程修改。 声明为 volatile 的字段不受编译器优化(假定由单个线程访问)的限制。 这样可以确保该字段在任何时间呈现的都是最新的值。 volatile 修饰符通常用于由多个线程访问但不使用 lock 语句对访问进行序列化的字段。 volatile 关键字可应用于以下类型的字段: 引用类型。 指针类型(在不安全的上下文中)。 请注意,虽然指针本身可以是可变的,但是它指向的对象不能是可变的。 换句话说,您无法声明“指向可变对象的指针”。 类型,如 sbyte、byte、short、ushort、int、uint、char、float 和 bool。 具有以下基类型之一的枚举类型:byte、sbyte、short、ushort、int 或 uint。 已知为引用类型的泛型类型参数。 IntPtr 和 UIntPtr。 可变关键字仅可应用于类或结构字段。 不能将局部变量声明为 volatile。 示例 下面的示例说明如何将公共字段变量声明为 volatile。 C#

下面的示例演示如何创建辅助线程,并用它与主线程并行执行处理。 有关多线程处理的背景信息,请参见托管线程处理和线程处理(C# 和 Visual Basic)。 C#

龙生   30 Jun 2014
View Details

ManualResetEvent详解

1. 源码下载: 下载地址:http://files.cnblogs.com/tianzhiliang/ManualResetEventDemo.rar Demo: 2. ManualResetEvent详解 ManualResetEvent 允许线程通过发信号互相通信。通常,此通信涉及一个线程在其他线程进行之前必须完成的任务。当一个线程开始一个活动(此活动必须完成后,其他线程才能开始)时,它调用 Reset 以将 ManualResetEvent 置于非终止状态,此线程可被视为控制 ManualResetEvent。调用 ManualResetEvent 上的 WaitOne 的线程将阻止,并等待信号。当控制线程完成活动时,它调用 Set 以发出等待线程可以继续进行的信号。并释放所有等待线程。一旦它被终止,ManualResetEvent 将保持终止状态(即对 WaitOne 的调用的线程将立即返回,并不阻塞),直到它被手动重置。可以通过将布尔值传递给构造函数来控制 ManualResetEvent 的初始状态,如果初始状态处于终止状态,为 true;否则为 false。   using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; namespace ManualResetEventDemo {     class MREDemo     {         private ManualResetEvent _mre;         public MREDemo()         {             this._mre = new ManualResetEvent(true);         }         public void CreateThreads()         {             Thread t1 = new Thread(new ThreadStart(Run));             t1.Start();             Thread t2 = new Thread(new ThreadStart(Run));             t2.Start();         }         public void Set()         {             this._mre.Set();         }         public void Reset()         {             this._mre.Reset();         }         private void Run()         {             string strThreadID = string.Empty;             try             {                 while (true)                 {                     // 阻塞当前线程                     this._mre.WaitOne();                     strThreadID = Thread.CurrentThread.ManagedThreadId.ToString();                     Console.WriteLine("Thread(" + strThreadID + ") is running…");                     Thread.Sleep(5000);                 } […]

龙生   30 Jun 2014
View Details

浅谈ThreadPool 线程池

相关概念:     线程池可以看做容纳线程的容器;     一个应用程序最多只能有一个线程池;     ThreadPool静态类通过QueueUserWorkItem()方法将工作函数排入线程池;     每排入一个工作函数,就相当于请求创建一个线程; 线程池的作用: 线程池是为突然大量爆发的线程设计的,通过有限的几个固定线程为大量的操作服务,减少了创建和销毁线程所需的时间,从而提高效率。 如果一个线程的时间非常长,就没必要用线程池了(不是不能作长时间操作,而是不宜。),况且我们还不能控制线程池中线程的开始、挂起、和中止。 什么时候使用ThreadPool? ThreadPool 示例一 : ThreadPool_1.cs using System; using System.Text; using System.Threading; namespace 多线程 { public class Example { public static void Main() { // Queue the task.             ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadProc)); Console.WriteLine("Main thread does some work, then sleeps."); Thread.Sleep(1000); Console.WriteLine("Main thread exits."); } static void ThreadProc(Object stateInfo) { // No state object was passed to QueueUserWorkItem, // so stateInfo is null.             Console.WriteLine("Hello from the thread pool."); } } } ThreadPool 示例二 : ThreadPool_2.cs using System; using System.Collections.Generic; using System.Text; using System.Threading; namespace CS_Test { class ThreadPool_Demo { // 用于保存每个线程的计算结果         static int[] result = new int[10]; //注意:由于WaitCallback委托的声明带有参数, //      所以将被调用的Fun方法必须带有参数,即:Fun(object obj)。         static void Fun(object obj) { int n = (int)obj; //计算阶乘             int fac = 1; for (int i = 1; i <= n; i++) { fac *= i; } //保存结果             result[n] = fac; } static void Main(string[] args) { //向线程池中排入9个工作线程             for (int i = 1; i <= 9 ; i++) { //QueueUserWorkItem()方法:将工作任务排入线程池。                 ThreadPool.QueueUserWorkItem(new WaitCallback(Fun),i); // Fun 表示要执行的方法(与WaitCallback委托的声明必须一致)。 // i   为传递给Fun方法的参数(obj将接受)。             } //输出计算结果             for (int i = 1; i <= 9; i++) { Console.WriteLine("线程{0}: {0}! = {1}",i,result[i]); } } } } ThreadPool的作用: 参考来源: C#多线程学习(四) 多线程的自动管理(线程池)  [叩响C#之门]写给初学者:多线程系列( 十一)——线程池(ThreadPool) from:http://www.cnblogs.com/xugang/archive/2010/04/20/1716042.html

龙生   30 Jun 2014
View Details

在Visual Studio 2012使用单元测试

本人之前很少使用单元测试,总觉得平时的工作写得代码够多了,单元测试还要再编码,增加大量工作量,相信不少程序猿也是这么认为吧。

但是我认为,在必要的时候正确运用单元测试,可以大大缩短代码的调试时间,正所谓磨刀不误砍柴工,在此建议仍不会单元测试的,还是学一下吧。当然本人在单元测试方面还是菜鸟,无论是鸡蛋鲜花都欢迎。

最近公司请微软的人做了一些关于使用VS2012进行单元测试的小培训,小生微做笔记,结合朦胧的记忆,在此自行总结,并分享之。废话少说,先上笔记:

1.先写单元测试(依我愚见,应该是接口先行,如果有的话) -> 测试失败 -> 以最小的改动(即编写实际代码)使测试通过(而在VS2012中已经不能通过现有项目直接生成测试项目了,我觉得这个功能还是应该保留,微软总是这副德行,强迫用户适应他们的产品,但是又不得不适应);

2.不因单元测试而追加功能(代码),即逻辑不受单元测试影响;

3.改变了代码的逻辑(增删改),应及时运行单元测试;

4.在测试方法声明Attribute —— TestCategory("分类或特征名");

5.在单元测试项目添加Fakes程序集分离外部依赖(如数据库访问,获取配置信息等);

6.初始化单元测试类中的成员等信息,可添加方法并声明Attribute[TestInitialize](方法需为public);

7.测试自动化。

以下我将通过自己编写代码来验证上述笔记中的部分要点。有些未涉及,以后再尝试了。

1.新建一个单元测试项目,并添加类XmlSerializationTest,代码如下:

由于我这个项目是对Xml序列化进行测试,因而前提是项目中已存在了一个UserModel类,并且在单元测试项目中添加相应引用

接下来在编写实际的代码,微软讲师建议我们先在测试项目编写,待通过单元测试后再将代码移到相应的项目下面。

 XmlSerialization

现在整个解决方案结构如下图所示

保证整个解决方案生成成功之后点击菜单“测试” -〉 “运行” -〉 “所有测试”,发现测试不通过,于是就按照第一点笔记,以最小改动使测试通过。

修改WriteXml方法为:

运行测试通过。对于返回值为bool的方法,个人建议进行至少两次Assert,也就是分别对返回true和false进行Assert,因而我们再对WriteXml方法添加一个测试方法,

运行测试,不通过,所以我得要好好改我的代码了,在改动当中坚持执行我的第三点笔记,改动代码及时运行单元测试。

我们发现这个类的构造函数多了一个参数,是对象序列化后保存的路径,且该类对应的测试类都需要用到,因而我希望在每次测试进行单元测试前先将对象的构建,这就是第六点笔记提供的“声明Attribute[TestInitialize]”(注意必须是public方法,我用private方法运行测试是不通过)。改造后的测试类如下:

还可以分析测试代码的覆盖率,如下图所示在测试资源管理器点击“运行”下的相应选项。

居然是100%,真不知道这个东西微软是怎么分析出来的。

把类XmlSerializationTest移到相应的项目,更改命名空间,在测试项目添加相应引用,测试通过。

将解决方案添加到TFS源码管理,我这边是用的是微软云TFS免费版。

收工。

VS提供了很多类型的测试,负载、UI等等测试,感觉还是蛮强大的。

from:http://www.cnblogs.com/FreeDong/archive/2013/06/10/3129625.html

System.MissingMethodException:Method not found:+解决方案

中文版本提示:System.MissingMethodException: 找不到方法:… 英文版本提示:System.MissingMethodException: Method not found:… 导致此异常的原因是引用程集版本冲突,通常可能是因为同一个项目(DLL)被多个项目(DLL)引用,导致新加的方法找不到,但是不会抛编译期异常,而是抛运行期异常。跟踪调试的时候根本无法运行到调用的地方,所以,很容易导致该解决该问题无从下手。 个人觉得这应该是VS的一个BUG,我用的是VS2008,不知道其它版本有没有同样的问题。 解决方法:修改引用的项目的AssemblyInfo.cs下的版本号,重新编译、发布。   问题解决方法: 不是补丁问题也不是版本号修改。问题发生在,提示找不到的方法,有的版本中确实未找到。替换使用的方法问题解决。 can’t get hostname for your address     Navicat for Mysql 远程连接数据库 出现 1042-Can’t get hostname for your address 错误! 是什么问题。 编辑/etc/my.cnf,在:[mysqld]内添加一行:skip-name-resolveMySQL 忽略数据库表名大小写修改/etc/my.cnf,在 [mysqld] 内添加一行:lower_case_table_names=1 from:http://blog.csdn.net/jglie/article/details/6863067

龙生   05 Jun 2014
View Details

ASP.NET中BasePage的几种设计方式

使用它主要是为了复用代码的公用部分下面是整理出来三种实现方式:准备工作:1 先在BasePage.cs中创建部分类BasePage 比在创建接下来用到的用于演示的方法BaseLoad代码:public partial  class BasePage : System.Web.UI.Page{        protected void BaseLoad()        {            string code = Request.QueryString["id"];            if (String.IsNullOrEmpty(code))            {                Response.End();            }        }}2 使用BasePage.cs的Default.aspxDefault.aspx.cs代码:public partial class Default : BasePage{        protected  void Page_Load(object sender, EventArgs e)    {        //do something    }}一、重写BasePage的OnLoad方法,该方法会触发OnLoad事件BasePage.cs代码:public partial  class BasePage : System.Web.UI.Page{    protected override void OnLoad(EventArgs e)    {        BaseLoad();        base.OnLoad(e);    }}二、在构造函数中把BaseLoad注册到基类的this.Page.PreLoad事件BasePage.cs代码:public partial  class BasePage : System.Web.UI.Page{    public BasePage()    {        this.Page.PreLoad += BaseLoad;    }}三、这种方式让继承他的子类方式看起来有些怪异(不能在里面使用Page_Load)BasePage.cs 代码:public abstruct class BasePage : System.Web.UI.Page{    protected void Page_Load()    {        string code = Request.QueryString["id"];        if (String.IsNullOrEmpty(code))        {            Response.End();        }        PageLoad();        }    protected […]

龙生   29 May 2014
View Details
1 34 35 36 47