C#

如何在 Nuget 发布自己的类库包

我们可以将自己实现的类库发布到 Nuget 上,方便在未来开发应用程序时,对已有代码或结构进行复用。以下是在 Nuget 发布自己类库的一个简单介绍。

1. 首先,我们需要到 nuget.org 注册并 获取 API key

2. 随后,下载 Nuget 命令行工具,建议将 nuget.exe 注册到系统的环境变量中,方便后续步骤的操作
Continue reading

最佳实践:根据条件获取集合的部分结果

很多场景下,我们需要根据一个条件判定某一集合中是否存在从中选取部分符合条件的元素用于后续操作。我们有很多方式可以实现这种需求,比如 纯手工对集合进行遍历,yield return,Any(),Count() 或 Count 属性,那么,这些实现方式对效率的影响如何?哪种实现效率较优呢?

我们来做一次实验。

首先我们定义一个类,并初始化包含有 1 万个该类型实例的集合。

    public class Item
    {
        public Guid Id { get; set; }
        public string Name { get; set; }
        public bool Gender { get; set; }
        public int Age { get; set; }
        public DateTime Birthday { get; set; }
        public string Address { get; set; }
        public string Email { get; set; }
    }

Continue reading

如何将 XML 的 XSD 定义转换为 C# 类

当我们将一些配置数据存储在 XML 文档中,或希望自定义某种 XML 格式的文档时,最好先去定义 XML 对应的 XSD 规范。定义 XSD 后,我们不仅可以在 VS 等 IDE 中对相应的 XML 文件的语法进行自动检查或属性匹配,同时也可以自动生成对应的实体类,简化 XML 的创建、修改以及读取。

打开 VS,在 XSD 文件上点击鼠标右键,点选 Open Command Prompt

Continue reading

C#: 一个方法执行超时 timeout 检查的实现

我们经常有这样的需求:如果一个方法的执行,超过了一个设定时间(timeout)就需要立即返回不再继续,这里我利用 C# 异步委托的 AsyncWaitHandle 来尽量简便的实现这一需求。

具体实现如下。注意,这里需要被调用的方法遵守 delegate TR TimeOutDelegate(T param); 形式的方法签名,如有其他需要,可以自行定制也很方便。

namespace TimeOutHelper
{
    #region using directives

    using System;
    using System.Collections.Generic;
    using System.Globalization;
    using System.Linq;
    using System.Threading;

    #endregion using directives

    internal class Program
    {
        public delegate TR TimeOutDelegate<in T, out TR>(T param);

        private static void Main()
        {
            Dictionary<Guid, string> result;
            Console.WriteLine(TimeoutFunction.Execute(Test, "Hello, World!", out result, TimeSpan.FromSeconds(3)));
            Console.WriteLine("Hello, World!");
            Console.ReadKey();
        }

        public static Dictionary<Guid, string> Test(string sourceString)
        {
            var result = sourceString.ToDictionary(
                character => Guid.NewGuid(),
                character => character.ToString(CultureInfo.InvariantCulture));
            Thread.Sleep(4000);
            return result;
        }

        public static class TimeoutFunction
        {
            /// <summary>
            ///     Execute a method with timeout check
            /// </summary>
            /// <typeparam name="T">Target method parameter type</typeparam>
            /// <typeparam name="TR">The result type of execution</typeparam>
            /// <param name="timeoutMethod">Target method</param>
            /// <param name="param">Target method parameter</param>
            /// <param name="result">The result of execution</param>
            /// <param name="timeout">Set timeout length</param>
            /// <returns>Is timeout</returns>
            public static Boolean Execute<T, TR>(
                TimeOutDelegate<T, TR> timeoutMethod, T param, out TR result, TimeSpan timeout)
            {
                var asyncResult = timeoutMethod.BeginInvoke(param, null, null);
                if (!asyncResult.AsyncWaitHandle.WaitOne(timeout, false))
                {
                    result = default(TR);
                    return true;
                }
                result = timeoutMethod.EndInvoke(asyncResult);
                return false;
            }
        }
    }
}

C#: 字符串连接 (+=) 与 StringBuilder 效率分析

在 C# 或 Java 中,我们可以使用诸如 StringBuilder, StringBuffer 等方式对大量字符串进行拼接操作。当然,我们也可以直接使用 字符串连接 (+=) 的方式进行拼接操作。但是,两种主要方式在效率上有何区别呢?我们是否需要针对这两类方式进行区别场景的使用呢?针对于此,我做了如下测试,以证明两种不同方式连接字符串的效率临界值。(关于Java中StringBuilder和StringBuffer的区别,可以参阅这篇文章

测试方法是:重复连接字符串 “Hello World!” 1次到40次,在每次连接的过程中都分别采用 String Connection (+=) 和 StringBuilder 的 Append()方法进行1000次,并分别计算出两种方法在这1000次运算过程中的获胜比率。通过多次试验,得到如下统计:

第一次:
StringBuilder Efficiency Test 1
Continue reading

C#: 双检锁 (Double Checked Locking)

以下内容是我在公司作为新人培训讲师时对于作业的一次评价,简单介绍了双解锁的作用,可以作为一个简单的参考。

大家可以思考这样一个问题,一个程序可以对应多少个日志文件?对于我们这个小程序来说1个就够了,很多同学在设计Logger类的时候都是在构造方法或初始化方法中生成日志文件的,也就是说,这基本上等价于一个Logger的实例对应一个新的日志文件(或重新对同一文件重新开启流)。

Logger myLogger = new Logger(@“D:my.log”);

如何才能阻止Logger被随意的new出实例呢?我们可以修改Logger的构造方法,让构造方法成为private的,这样就能实现谁都不能new出Logger实例的目的了。但是,访问修饰符(如private)只是影响类之外的使用,对于Logger类的内部,是不会受到private的影响的,也就是说,我们依然可以在Logger类中使用new来创建实例,这正是我们想要的,我们可以为用户提前创建好一个实例,并作为这个类的静态成员存在,从而得到这样一个Logger类:
Continue reading