C# 常用

转义
转义符     字符名

\'  单引号
\"  双引号
\\  反斜杠
\0  空字符
\a  感叹号
\b  退格
\f  换页
\n  新行
\r  回车
\t  水平 tab
\v  垂直tab

输出转义字符串

Console.WriteLine(@"c:\temp\newfile.txt");
枚举
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;

namespace ConsoleApp4
{

    static class Program
    {
        public static DB EnumObj { get; set; }
        static void Main(string[] args)
        {
            var aaa = EnumObj.Split();
            var bbb = (DB)7;
            var ccc = (DB)15;

            //遍历枚举
            foreach (DB enum2 in Enum.GetValues(typeof(DB)))
            {
                //enum2 = DB.Read;
                var Int = (int)enum2;
                var Str = enum2.ToString();
                var Description = GetDescriptionByEnum(enum2);
            }
            Console.ReadKey();
        }

        // Flags 可以让枚举值以枚举值之和形式提现。有一个前提:(int)大的枚举值必须大过其小于此值枚举值之和
        //比如:ReadWrite > None + Write + Read
        [Flags]
        public enum DB
        {
            None = 0,
            Write = 1,
            [Description("写")]
            Read = 2,
            ReadWrite = 4,
            Max = 8
        }
        //枚举、字符串、数字相互转换
        public static int EnumConvertToInt(DB db) => (int)db;
        public static string EnumConvertToString(DB db) => db.ToString();
        public static DB StringConvertToEnum(string str) => (DB)Enum.Parse(typeof(DB), str);
        public static DB IntConvertToEnum(int i) => (DB)i;
        // 将枚举转化为IEnumerable列表
        public static IEnumerable<T> Split<T>(this T enums) => Enum.GetValues(enums.GetType()).Cast<T>();

        /// <summary>
        /// 获取枚举的 Description 值
        /// </summary>
        /// <param name="enumValue"></param>
        /// <returns></returns>
        public static string GetDescriptionByEnum(Enum enumValue)
        {
            string value = enumValue.ToString();
            FieldInfo field = enumValue.GetType().GetField(value);
            //获取描述属性  
            object[] objs = field.GetCustomAttributes(typeof(DescriptionAttribute), false);
            //当描述属性没有时,直接返回名称
            return objs.Length == 0 ? value : ((DescriptionAttribute)objs[0]).Description;
        }
    }
}
生成GUID
//默认为:D(第三种)
var uuid = Guid.NewGuid().ToString(); // 9af7f46a-ea52-4aa3-b8c3-9fd484c2af12
var uuidN = Guid.NewGuid().ToString("N"); // e0a953c3ee6040eaa9fae2b667060e09
var uuidD = Guid.NewGuid().ToString("D"); // 9af7f46a-ea52-4aa3-b8c3-9fd484c2af12
var uuidB = Guid.NewGuid().ToString("B"); // {734fd453-a4f8-4c5d-9c98-3fe2d7079760}
var uuidP = Guid.NewGuid().ToString("P"); // (ade24d16-db0f-40af-8794-1e08e2040df3)
var uuidX = Guid.NewGuid().ToString("X"); // {0x3fa412e3,0x8356,0x428f,{0xaa,0x34,0xb7,0x40,0xda,0xaf,0x45,0x6f}}
压缩

NuGet安装 System.IO.Compression.ZipFile

处理zip存档及其文件条目的方法分布在三个类中:ZipFileZipArchiveZipArchiveEntry

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApp
{
    /// <summary>
    /// 文件压缩类
    /// </summary>
    public static class ZipHelper
    {
        /// <summary>
        /// 文件夹压缩成ZIP
        /// </summary>
        /// <param name="zipPath">压缩文件路径</param>
        /// <param name="zipFolderPath">被压缩文件夹目录</param>
        public static void CompressFolderZip(string zipPath, string zipFolderPath)
        {
            ZipFile.CreateFromDirectory(zipFolderPath, zipPath);
        }

        /// <summary>
        /// 文件压缩成ZIP
        /// </summary>
        /// <param name="filePath">被压缩文件路径</param>
        public static void CompressFileZip(string filePath)
        {
            string zipPath = string.Concat(Path.Combine(Path.GetDirectoryName(filePath), Path.GetFileNameWithoutExtension(filePath)), ".zip");
            CompressFileZip(zipPath, filePath);
        }

        /// <summary>
        /// 文件压缩成ZIP
        /// </summary>
        /// <param name="zipPath">压缩文件路径</param>
        /// <param name="filePath">被压缩文件路径</param>
        public static void CompressFileZip(string zipPath, string filePath)
        {
            using (FileStream zipFileToOpen = new FileStream(zipPath, FileMode.OpenOrCreate))
            {
                using (ZipArchive archive = new ZipArchive(zipFileToOpen, ZipArchiveMode.Update))
                {
                    archive.CreateEntryFromFile(filePath, Path.GetFileName(filePath));
                }
            }
        }

        /// <summary>
        /// 解压文件到指定目录
        /// </summary>
        /// <param name="zipPath">压缩文件路径</param>
        /// <param name="upZipDirPath">解压缩文件夹目录</param>
        public static void UnZip(string zipPath, string upZipDirPath = "")
        {
            if (string.IsNullOrEmpty(upZipDirPath))
            {
                upZipDirPath = Path.Combine(Path.GetDirectoryName(zipPath), Path.GetFileNameWithoutExtension(zipPath));
            }

            if (!Directory.Exists(upZipDirPath)) Directory.CreateDirectory(upZipDirPath);
            ZipFile.ExtractToDirectory(zipPath, upZipDirPath, true);
        }

        /// <summary>
        /// 获取Zip内部文件流
        /// </summary>
        /// <param name="zipPath">压缩文件Zip路径</param>
        /// <param name="fileName">压缩内部文件路径名称</param>
        /// <returns></returns>

        public static Stream GetZipFileStream(string zipPath, string fileName)
        {
            using (var zipFileToOpen = File.OpenRead(zipPath))
            {
                using (ZipArchive archive = new ZipArchive(zipFileToOpen, ZipArchiveMode.Read))
                {
                    using (var r = archive.GetEntry(fileName).Open())
                    {
                        return r;
                    }
                }
            }
        }

        /// <summary>
        /// 获取Zip内部所有文件名称
        /// </summary>
        /// <param name="zipPath">压缩文件Zip路径</param>
        /// <returns></returns>
        public static IEnumerable<string> GetZipFilesName(string zipPath)
        {
            using var file = File.OpenRead(zipPath);
            using var zip = new ZipArchive(file, ZipArchiveMode.Read);
            return zip.Entries.Select(z => z.FullName);

            ////遍历获取文件流
            //foreach (var entry in zip.Entries)
            //{
            //    using var stream = entry.Open();
            //}
        }
    }
}
深拷贝

        #region 深拷贝
        /// <summary>
        /// 深拷贝
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="source">需要拷贝数据</param>
        /// <returns></returns>
        public T Clone<T>(T source)
        {
            if (!typeof(T).IsSerializable)
                throw new ArgumentException("The type must be serializable.", "source");

            if (source == null)
                return default;

            IFormatter formatter = new BinaryFormatter();
            using (Stream stream = new MemoryStream())
            {
                formatter.Serialize(stream, source);
                stream.Seek(0, SeekOrigin.Begin);
                return (T)formatter.Deserialize(stream);
            }
        }

        /// <summary>
        /// 深拷贝2
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj">需要拷贝数据</param>
        /// <returns></returns>
        public T Clone2<T>(T obj)
        {
            if (!typeof(T).IsSerializable)
                throw new ArgumentException("The type must be serializable.", "source");

            if (ReferenceEquals(obj, null))
                return default;
            //创建内存流
            MemoryStream ms = new MemoryStream();
            //以二进制格式进行序列化
            BinaryFormatter bf = new BinaryFormatter();
            bf.Serialize(ms, obj);
            //反序列化当前实例到一个object
            ms.Seek(0, 0);
            T res = (T)bf.Deserialize(ms);
            //关闭内存流
            ms.Close();
            return res;
        }

Stream流
 /// <summary>
        /// 将 Stream 转成 byte[]
        /// </summary>
        /// <param name="bytes"></param>
        /// <returns></returns>
        public byte[] StreamToBytes(Stream stream)
        {
            byte[] bytes = new byte[stream.Length];
            stream.Read(bytes, 0, bytes.Length);
            stream.Seek(0, SeekOrigin.Begin);
            stream.Flush();
            stream.Close();
            return bytes;
        }

        /// <summary>
        /// 将 byte[] 转成 Stream
        /// </summary>
        /// <param name="bytes"></param>
        /// <returns></returns>
        public Stream BytesToStream(byte[] bytes)
        {
            return new MemoryStream(bytes);
        }

        /// <summary>
        /// 将字符串 转成 byte[]
        /// </summary>
        /// <param name="bytes"></param>
        /// <returns></returns>
        public byte[] StringToBytes(string str)
        {
            UnicodeEncoding converter = new UnicodeEncoding();
            byte[] bytes = converter.GetBytes(str);
            string inputString = converter.GetString(bytes);

            inputString = System.Convert.ToBase64String(bytes);
            bytes = System.Convert.FromBase64String(inputString);
            return bytes;
        }

        /// <summary>
        /// 写文件流
        /// </summary>
        /// <param name="fileBytes">文件流</param>
        /// <param name="FullName">文件完全路径+文件名(包括后缀名)</param>
        public void SaveFileByStream(byte[] fileBytes, string FullName)
        {
            File.WriteAllBytes(FullName, fileBytes);
        }

        /// <summary>
        /// 写文件流
        /// </summary>
        /// <param name="stream">文件流</param>
        /// <param name="FullName">文件完全路径+文件名(包括后缀名)</param>
        public void StreamToFile(Stream stream, string fileName)
        {
            // 把 Stream 转换成 byte[]
            byte[] bytes = new byte[stream.Length];
            stream.Read(bytes, 0, bytes.Length);
            // 设置当前流的位置为流的开始
            stream.Seek(0, SeekOrigin.Begin);
            // 把 byte[] 写入文件
            FileStream fs = new FileStream(fileName, FileMode.Create);
            BinaryWriter bw = new BinaryWriter(fs);
            bw.Write(bytes);
            bw.Close();
            fs.Close();
        }

        /// <summary>
        /// 读文件流
        /// </summary>
        /// <param name="fileFullName">文件地址路径(路径+文件名称+文件后缀)</param>
        /// <returns></returns>
        public Stream FileToStream(string fileFullName)
        {
            // 打开文件  
            using (FileStream fileStream = new FileStream(fileFullName, FileMode.Open, FileAccess.Read, FileShare.Read))
            {
                // 读取文件的 byte[]  
                byte[] bytes = new byte[fileStream.Length];
                fileStream.Read(bytes, 0, bytes.Length);
                return new MemoryStream(bytes);
            }
        }
计时器
using System.Diagnostics;            
//Restart和Reset 的区别:
//Restart:计时器刻度变成了0并开始运行,
//Reset:计时器刻度变成了0但是并没有运行,需要重新 Start
Stopwatch timer = new Stopwatch();
timer.Start();
timer.Stop();

timer.Restart();
timer.Stop();

timer.Reset();
timer.Start();
Thread.Sleep(1000);
timer.Stop();

Console.WriteLine(timer.ElapsedTicks);//计时器刻度,--------最精确---------
Console.WriteLine(timer.ElapsedMilliseconds);//毫秒
Console.WriteLine(timer.Elapsed.TotalSeconds);//秒
Console.WriteLine(Math.Round(timer.Elapsed.TotalSeconds, 2)); //秒,保留两位
Console.WriteLine(timer.Elapsed.TotalMinutes);//分钟                
Console.WriteLine(timer.Elapsed.TotalHours);//小时        
Console.WriteLine(timer.Elapsed);  //时间格式

//--------方法耗时---------
var time1 = Time(() =>
{
    Console.WriteLine(11);
});
Console.WriteLine($"毫秒耗时:{time1}");



static long Time(Action action)
{
    var stopwatch = new Stopwatch();
    stopwatch.Start();
    action();
    stopwatch.Stop();
    return stopwatch.ElapsedMilliseconds;
}
Debug模式输出信息
#if DEBUG
    Console.WriteLine("DEBUG");
#endif

#if DEBUG
    // 在 Debug 模式下编译时执行的代码
#else
    // 在 Release 模式下编译时执行的代码
#endif

#if TRACE
    //诊断信息,在DEBUG和Release下都会运行
    Console.WriteLine("TRACE");
#endif


#if DEBUG
    Console.WriteLine("DEBUG");
#elif TRACE
    Console.WriteLine("TRACE");
#else
    Console.WriteLine("此代码不会运行");
#endif


//判断是否处于调试状态
if (Debugger.IsAttached)
{
    //Debug模式下进程会报错并终止
    Debug.Assert(false, "error");
    Debug.Fail("error");

    //打印信息
    Debug.Print("msg");
    Debug.WriteLine("msg");
    Debug.WriteLineIf(true, "msg");

    Trace.WriteLine(213);
}
else
{
    Console.WriteLine(123456789);
}
反射
//通过程序集和命名空间实体类名称获取Type
//Type.GetType("命名空间.实体类,程序集名称");
Type programType = Type.GetType("ConsoleApp1.Program,ConsoleApp1");


//获取实体类的单例赋值给接口
IEnumerable enumerable = Activator.CreateInstance(typeof(Hashtable)) as IEnumerable;
IList<string> list = Activator.CreateInstance(typeof(List<string>)) as IList<string>;

//反射执行方法
//Assembly ass = Assembly.LoadFrom("test.dll");//加载C#程序集
//Type type = ass.GetType("test.Program");//调用类,namespace名.类名
Type type = typeof(Exec);
string methodName = "NUM";
var argtypes = new Type[] { typeof(int) };
var bindingAttr = BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance;
MethodInfo? method = type.GetMethod(methodName, bindingAttr, argtypes);
object? instance = type.IsAbstract && type.IsSealed ? null : Activator.CreateInstance(type);
object? result = method?.Invoke(instance, new object[] { 1 });
if (result!=null)
{
	//Do
}



public class Exec
{
	public int NUM(int a) => a + 1;
	public static int NUM2(int a) => a + 2;
	public void NoNUM(int a) => Console.WriteLine(a);
}
批量注入
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;


namespace WebApplication4
{
    public static class IServiceCollectionExtenions
    {
        /// <summary>
        /// 批量注入
        /// </summary>
        /// <param name="services"></param>
        /// <param name="assemblyName"></param>
        /// <param name="lifetime"></param>
        public static void BatchRegisterService(this IServiceCollection services, string assemblyName = "", ServiceLifetime lifetime = ServiceLifetime.Scoped)
        {
            //排除程序集中的接口、私有类、抽象类
            var typeList = RuntimeHelper.GetAllAssemblies(assemblyName).SelectMany(t => t.GetTypes()).Where(t => t.IsClass
            && !t.IsInterface && !t.IsSealed && !t.IsAbstract).ToList();
            //历遍程序集中的类
            foreach (var type in typeList)
            {
                //查找当前类继承且包含当前类名的接口
                var interfaceType = type.GetInterfaces().Where(o => o.Name.Contains(type.Name)).FirstOrDefault();
                if (interfaceType != null)
                {
                    //根据生命周期注册
                    switch (lifetime)
                    {
                        case ServiceLifetime.Scoped:
                            services.AddScoped(type, interfaceType);
                            break;
                        case ServiceLifetime.Singleton:
                            services.AddSingleton(type, interfaceType);
                            break;
                        case ServiceLifetime.Transient:
                            services.AddTransient(type, interfaceType);
                            break;
                    }
                }
            }
        }

        /// <summary>
        /// 用DI批量注入接口程序集中对应的实现类。
        /// <para>
        /// 需要注意的是,这里有如下约定:
        /// IUserService --> UserService, IUserRepository --> UserRepository.
        /// </para>
        /// </summary>
        /// <param name="service"></param>
        /// <param name="interfaceAssemblyName">接口程序集的名称(不包含文件扩展名)</param>
        /// <returns></returns>
        public static IServiceCollection RegisterAssembly(this IServiceCollection service, string interfaceAssemblyName)
        {
            if (string.IsNullOrEmpty(interfaceAssemblyName))
                throw new ArgumentNullException(nameof(interfaceAssemblyName));

            var assembly = RuntimeHelper.GetAssembly(interfaceAssemblyName);
            if (assembly == null)
            {
                throw new DllNotFoundException($"the dll \"{interfaceAssemblyName}\" not be found");
            }

            //过滤掉非接口及泛型接口
            var types = assembly.GetTypes().Where(t => t.GetTypeInfo().IsInterface && !t.GetTypeInfo().IsGenericType);

            foreach (var type in types)
            {
                var implementTypeName = type.Name.Substring(1);
                var implementType = RuntimeHelper.GetImplementType(implementTypeName, type);
                if (implementType != null)
                    service.AddTransient(type, implementType);
            }
            return service;
        }

        /// <summary>
        /// 用DI批量注入接口程序集中对应的实现类。
        /// </summary>
        /// <param name="service"></param>
        /// <param name="interfaceAssemblyName">接口程序集的名称(不包含文件扩展名)</param>
        /// <param name="implementAssemblyName">实现程序集的名称(不包含文件扩展名)</param>
        /// <returns></returns>
        public static IServiceCollection RegisterAssembly(this IServiceCollection service, string interfaceAssemblyName, string implementAssemblyName)
        {
            if (string.IsNullOrEmpty(interfaceAssemblyName))
                throw new ArgumentNullException(nameof(interfaceAssemblyName));
            if (string.IsNullOrEmpty(implementAssemblyName))
                throw new ArgumentNullException(nameof(implementAssemblyName));

            var interfaceAssembly = RuntimeHelper.GetAssembly(interfaceAssemblyName);
            if (interfaceAssembly == null)
            {
                throw new DllNotFoundException($"the dll \"{interfaceAssemblyName}\" not be found");
            }

            var implementAssembly = RuntimeHelper.GetAssembly(implementAssemblyName);
            if (implementAssembly == null)
            {
                throw new DllNotFoundException($"the dll \"{implementAssemblyName}\" not be found");
            }

            //过滤掉非接口及泛型接口
            var types = interfaceAssembly.GetTypes().Where(t => t.GetTypeInfo().IsInterface && !t.GetTypeInfo().IsGenericType);

            foreach (var type in types)
            {
                //过滤掉抽象类、泛型类以及非class
                var implementType = implementAssembly.DefinedTypes
                    .FirstOrDefault(t => t.IsClass && !t.IsAbstract && !t.IsGenericType &&
                                         t.GetInterfaces().Any(b => b.Name == type.Name));
                if (implementType != null)
                {
                    service.AddTransient(type, implementType.AsType());
                }
            }

            return service;
        }
    }
}
字符串/字母/繁简体转换

NuGet安装 ToolGood.Words
Github地址:https://github.com/toolgood/ToolGood.Words



// 转成简体
WordsHelper.ToSimplifiedChinese("我愛中國");
WordsHelper.ToSimplifiedChinese("我愛中國", 1);// 港澳繁体 转 简体
WordsHelper.ToSimplifiedChinese("我愛中國", 2);// 台湾正体 转 简体
                                           // 转成繁体
WordsHelper.ToTraditionalChinese("我爱中国");
WordsHelper.ToTraditionalChinese("我爱中国", 1);// 简体 转 港澳繁体
WordsHelper.ToTraditionalChinese("我爱中国", 2);// 简体 转 台湾正体
                                            // 转成全角
WordsHelper.ToSBC("abcABC123");
// 转成半角
WordsHelper.ToDBC("abcABC123");
// 数字转成中文大写
WordsHelper.ToChineseRMB(12345678901.12);
// 中文转成数字
WordsHelper.ToNumber("壹佰贰拾叁亿肆仟伍佰陆拾柒万捌仟玖佰零壹元壹角贰分");
// 获取全拼
WordsHelper.GetPinyin("我爱中国");//WoAiZhongGuo   
WordsHelper.GetPinyin("我爱中国", ",");//Wo,Ai,Zhong,Guo   
WordsHelper.GetPinyin("我爱中国", true);//WǒÀiZhōngGuó

// 获取首字母
WordsHelper.GetFirstPinyin("我爱中国");//WAZG
// 多音字获取全部拼音
WordsHelper.GetAllPinyin('传');//Chuan,Zhuan
// 获取姓名
WordsHelper.GetPinyinForName("单一一");//ShanYiYi
WordsHelper.GetPinyinForName("单一一", ",");//Shan,Yi,Yi
WordsHelper.GetPinyinForName("单一一", true);//ShànYīYī




public static class WordHelper
{
    /// <summary>
    /// 转拼音字母
    /// </summary>
    public static string ToPinYin(this string str) => WordsHelper.GetPinyin(str);

    /// <summary>
    /// 转拼音首字母
    /// </summary>
    public static string ToPinYinFirst(this string str) => WordsHelper.GetFirstPinyin(str);

    /// <summary>
    /// 转中文简体
    /// </summary>
    public static string ToSimplifiedChinese(this string str) => WordsHelper.ToSimplifiedChinese(str);

    /// <summary>
    /// 转中文繁体字
    /// </summary>
    public static string ToTraditionalChinese(this string str) => WordsHelper.ToTraditionalChinese(str);
}
随机数字
// 随机数
Random ran = new Random();
Console.WriteLine(ran.Next(999));
Console.WriteLine(ran.Next(100, 999));

//获取200个随机数
var ran2 = System.Security.Cryptography.RandomNumberGenerator.Create();
byte[] bytes = new byte[200];
ran2.GetBytes(bytes);
foreach (var b in bytes)
{
    Console.WriteLine(b);
}

//获取200个随机数 .net 6 +
var newran = System.Security.Cryptography.RandomNumberGenerator.GetBytes(200);
foreach (var b in newran)
{
    Console.WriteLine(b);
}
随机字符串密码

/// <summary>
/// 生成随机字符(数字+字母)
/// </summary>
/// <param name="length">字符长度</param>
/// <returns>随机字符组成的字符串</returns>
public string GetRandomStr(int length)
{
    char[] arrChar ={
    '0','1','2','3','4','5','6','7','8','9',
    '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',
    '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'
    };

    System.Text.StringBuilder sb = new System.Text.StringBuilder();
    int arrCharLength = arrChar.Length;
    Random rd = new Random();
    for (int i = 0; i < length; i++)
    {
        sb.Append(arrChar[rd.Next(arrCharLength)]);
    }
    return sb.ToString();
}

/// <summary>
/// 生成随机字符
/// </summary>
/// <param name="length">字符长度</param>
/// <param name="number">是否包含数字</param>
/// <param name="lower">是否包含小写字母</param>
/// <param name="upper">是否包含大写字母</param>
/// <param name="symbol">是否包含特殊字母</param>
/// <returns>随机字符组成的字符串</returns>
public string GetRandomString(int length, bool number = true, bool lower = true, bool upper = true, bool symbol = false)
{
    char[] numberChars = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
    char[] lowerChars = 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' };
    char[] upperChars = 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' };
    //反斜杠是转义符,\\\" 代表 \"
    char[] symbolChars = "\\\"!#$%&'()*+,-./:;<=>?@[]^_`{|}~".ToArray();

    IEnumerable<char> charList = Enumerable.Empty<char>();
    if (number) charList = charList.Union(numberChars);
    if (lower) charList = charList.Union(lowerChars);
    if (upper) charList = charList.Union(upperChars);
    if (symbol) charList = charList.Union(symbolChars);

    var arrChar = charList.ToArray();
    int arrCharLength = arrChar.Length;
    if (arrCharLength == 0)
    {
        return string.Empty;
    }

    System.Text.StringBuilder sb = new System.Text.StringBuilder();
    Random rd = new Random();
    for (int i = 0; i < length; i++)
    {
        sb.Append(arrChar[rd.Next(arrCharLength)]);
    }
    return sb.ToString();
}
新线程执行循环任务
var newTask = Task.Factory.StartNew(() =>
{
    while (true)
    {
        // do something
        Thread.Sleep(1000 * 5);
    }
}, TaskCreationOptions.LongRunning);
区分系统
//获取当前系统信息
var osNameAndVersion = System.Runtime.InteropServices.RuntimeInformation.OSDescription;

//判断当前系统
var a = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
var b = Environment.OSVersion.Platform == PlatformID.Unix;

//此方法需要 .NET 5及以上版本
var c = System.OperatingSystem.IsLinux();
var d = System.OperatingSystem.IsWindows();

//路径问题
var a = Path.Combine("a","b");
string path =  RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "path".Replace('/', '\\') : "path".Replace('\\', '/');

if (OperatingSystem.IsLinux())
    path = path.Replace(@"\", Path.DirectorySeparatorChar.ToString());

Console.WriteLine($"Path.DirectorySeparatorChar: '{Path.DirectorySeparatorChar}'");
Console.WriteLine($"Path.AltDirectorySeparatorChar: '{Path.AltDirectorySeparatorChar}'");
Console.WriteLine($"Path.PathSeparator: '{Path.PathSeparator}'");
Console.WriteLine($"Path.VolumeSeparatorChar: '{Path.VolumeSeparatorChar}'");

// The example displays the following output when run on a Windows system:
//    Path.DirectorySeparatorChar: '\'
//    Path.AltDirectorySeparatorChar: '/'
//    Path.PathSeparator: ';'
//    Path.VolumeSeparatorChar: ':'

//
// The example displays the following output when run on a Linux system:
//    Path.DirectorySeparatorChar: '/'
//    Path.AltDirectorySeparatorChar: '/'
//    Path.PathSeparator: ':'
//    Path.VolumeSeparatorChar: '/'
大小写转换/匹配
string testStr = "AbcDefg";
//转换为大写
string UpTestStr = testStr.ToUpper();
//转换为小写
string LowTestStr = testStr.ToLower();

//忽略大小写比较
bool eq = UpTestStr.Equals(LowTestStr, StringComparison.OrdinalIgnoreCase);
bool eq2 = string.Equals(UpTestStr, LowTestStr, StringComparison.OrdinalIgnoreCase);

//字符串是否存在并忽略大小写,存在就是>=0,不存在返回-1
bool containsIgnoreCase = stringA.IndexOf(stringB, StringComparison.OrdinalIgnoreCase) >= 0;

//List忽略大小写
string[] arr = { "a", "b" };
var c = arr.Contains("A", StringComparer.OrdinalIgnoreCase);
Mock生成测试数据

官方文档

安装NugetInstall-Package Bogus


using Bogus;
using Bogus.Extensions.UnitedStates;
using System.Text.Json;

namespace ConsoleApp1;

public class Program
{

    static void Main(string[] args)
    {

        var userGenerator = new Faker<User>()
        .RuleFor(x => x.Id, x => x.IndexFaker + 1)
        .RuleFor(x => x.Gender, x => x.Person.Gender)
        .RuleFor(x => x.FirstName, (x, u) => x.Name.FirstName(u.Gender))
        .RuleFor(x => x.LastName, (x, u) => x.Name.LastName(u.Gender))
        .RuleFor(x => x.Email, (x, u) => x.Internet.Email(u.FirstName, u.LastName))
        .RuleFor(x => x.BirthDate, x => x.Person.DateOfBirth)
        .RuleFor(x => x.Company, x => x.Person.Company.Name)
        .RuleFor(x => x.Phone, x => x.Person.Phone)
        .RuleFor(x => x.Website, x => x.Person.Website)
        .RuleFor(x => x.SSN, x => x.Person.Ssn());

        var user = userGenerator.Generate();
        var list1 = userGenerator.Generate(100);
        var list2 = userGenerator.GenerateForever().Take(1000).ToList();

        string json = JsonSerializer.Serialize(list2);
    }
}

public class User
{
    public int Id { get; set; }
    public Bogus.DataSets.Name.Gender Gender { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Email { get; set; }
    public DateTime BirthDate { get; set; }
    public string Company { get; set; }
    public string Phone { get; set; }
    public string Website { get; set; }
    public string SSN { get; set; }
}
性能测试对比

官方文档

安装NugetInstall-Package BenchmarkDotNet
需要设置为Release模式启动,不然会报错

using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Order;
using BenchmarkDotNet.Running;

BenchmarkRunner.Run<Test>();

[RPlotExporter]
[MemoryDiagnoser]
[HtmlExporter]
[Orderer(SummaryOrderPolicy.FastestToSlowest)]
public class Test
{
    //此方法为基线,类中只有一个方法可以应用Baseline=true。
    [Benchmark(Baseline = true)]
    public void a() => Console.WriteLine(1);

    [Benchmark]
    public void b() => Console.WriteLine(2);

    [Benchmark]
    public void c() => Console.WriteLine(3);

}
获取字母大小写的所有组合

参考文档

public static List<string> LetterPermuteList(string input)
{
    List<string> list = new List<string>();
    for (int i = 0; i < 1 << input.Length; i++)
    {
        char[] combination = input.ToLower().ToCharArray();
        for (int j = 0; j < input.Length; j++)
            if (((i >> j) & 1) == 1)
                combination[j] = (char)(combination[j] - 32);
        list.Add(string.Concat(combination));
    }
    return list;
}
获取本机IP

/// <summary>
/// 获取本地IP地址
/// </summary>
private static string GetLocalIPAddress()
{
    var networkInterfaces = NetworkInterface.GetAllNetworkInterfaces();
    foreach (var network in networkInterfaces)
    {
        if (network.OperationalStatus != OperationalStatus.Up)
            continue;
        var properties = network.GetIPProperties();
        if (properties.GatewayAddresses.Count == 0)
            continue;

        foreach (var address in properties.UnicastAddresses)
        {
            if (address.Address.AddressFamily != AddressFamily.InterNetwork)
                continue;
            if (IPAddress.IsLoopback(address.Address))
                continue;
            return address.Address.ToString();
        }
    }
    return "127.0.0.1";
}

/// <summary>
/// 获取本地IP地址2
/// </summary>
private static string GetLocalIPAddress2()
{
    var result = Dns.GetHostEntry(Dns.GetHostName())
         .AddressList.FirstOrDefault(address =>
         address.AddressFamily == AddressFamily.InterNetwork)?.ToString();
    return result;
}
ChangeType
//通用方法:
public static T ChangeType<T>(object value) 
{
   var t = typeof(T);

   if (t.IsGenericType && t.GetGenericTypeDefinition().Equals(typeof(Nullable<>))) 
   {
       if (value == null) 
       { 
           return default(T); 
       }

       t = Nullable.GetUnderlyingType(t);
   }

   return (T)Convert.ChangeType(value, t);
}

//非通用方法:
public static object ChangeType(object value, Type conversion) 
{
   var t = conversion;

   if (t.IsGenericType && t.GetGenericTypeDefinition().Equals(typeof(Nullable<>))) 
   {
       if (value == null) 
       { 
           return null; 
       }

       t = Nullable.GetUnderlyingType(t);
   }

   return Convert.ChangeType(value, t);
}
AOP 获取方法名及参数和返回值

Nuget安装Rougamo.Fody

using Rougamo;
using Rougamo.Context;
using System.Text.Json;

namespace ConsoleApp1;

[AttributeUsage(AttributeTargets.Method)]

public class LoggingAttribute : MoAttribute
{
    public override void OnEntry(MethodContext context)
    {
        Console.WriteLine("执行方法 {0}() 开始, 参数:{1}.", context.Method.Name, JsonSerializer.Serialize(context.Arguments));
    }

    public override void OnException(MethodContext context)
    {
        Console.WriteLine("执行方法 {0}() 异常, {1}.", context.Method.Name, context.ToString());
    }

    public override void OnExit(MethodContext context)
    {
        Console.WriteLine("执行方法 {0}() 结束.", context.Method.Name);
    }

    public override void OnSuccess(MethodContext context)
    {
        Console.WriteLine("执行方法 {0}() 成功.", context.Method.Name);
        Console.WriteLine("方法返回值:" + context.ReturnValue);
    }
}


public class Test
{

    [Logging]
    public int a(int v) => v + 1;
}
时间
var dt = new DateTime(2022, 12, 26);

//本月第一天 
DateTime firstDay = dt.AddDays(1 - dt.Day);

//根据日期判断周几
int weekday = (int)dt.DayOfWeek == 0 ? 7 : (int)dt.DayOfWeek;

//本月第一天是周几 
int weekday = (int)firstDay.DayOfWeek == 0 ? 7 : (int)firstDay.DayOfWeek;

//本月第一周有几天 
int firstWeekEndDay = 7 - (weekday - 1);

//获取一年有多少周
var weekNum = ISOWeek.GetWeeksInYear(2022);

//根据日期判断是当年第几周
public static int GetWeekOfYear(this DateTime time) => new CultureInfo("zh-CN").Calendar.GetWeekOfYear(time, CalendarWeekRule.FirstDay, DayOfWeek.Monday);
public static int GetWeekOfYear2(this DateTime time) => new GregorianCalendar().GetWeekOfYear(time, CalendarWeekRule.FirstDay, DayOfWeek.Monday);

//根据日期判断是当年第几周(年初开始几天会取上一年年末的值)
var weekOrder = ISOWeek.GetWeekOfYear(new DateTime(2022, 12, 26));
public static int GetWeekOfYear(this DateTime time)
{
	DayOfWeek day = CultureInfo.InvariantCulture.Calendar.GetDayOfWeek(time);
	if (day >= DayOfWeek.Monday && day <= DayOfWeek.Wednesday) time = time.AddDays(3);
	return CultureInfo.InvariantCulture.Calendar.GetWeekOfYear(time, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
}

//根据日期判断是当月第几周(周一到周日)
public static int GetWeekNumberOfMonth(this DateTime date)
{
    DateTime firstDay = date.AddDays(1 - date.Day);
    while (date.Date.AddDays(1).DayOfWeek != CultureInfo.CurrentCulture.DateTimeFormat.FirstDayOfWeek) date = date.AddDays(1);
    return (int)Math.Truncate((double)date.Subtract(firstDay).TotalDays / 7f) + 1;
}

//根据日期判断是当月第几周(周日到周六)
public static int GetWeekNumberOfMonth2(this DateTime time) => new GregorianCalendar().GetWeekOfYear(time, CalendarWeekRule.FirstDay, DayOfWeek.Sunday) - new GregorianCalendar().GetWeekOfYear(time.AddDays(1 - time.Day), CalendarWeekRule.FirstDay, DayOfWeek.Sunday) + 1;


//根据日期判断是当月第几周(以每月的1号为第一周的开始,七天一周)
public static int WeekOfMonth(this DateTime d) => (d.Day - 1) / 7 + 1;
public static int WeekOfMonth2(this DateTime d) => (int)Math.Floor(d.Day / 7.0) + (d.Day % 7 == 0 ? 0 : 1);

确认本月有几周,输出每周开始时间和结束时间(输出月头和月尾大于4天的数据,并附带上月或者次月的数据)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    public class DateWeekService
    {
        public static MonthWeek GetMonthWeek(DateTime curDate)
        {
            int y = curDate.Year;
            int m = curDate.Month;
            int d = curDate.Day;
            int w = GetLocalDay(curDate);

            m = (w - d) >= 4 ? m - 1 : m;
            m = (curDate.AddDays(1 - curDate.Day).AddMonths(1).AddDays(-1).Day - d) + w < 4 ? m + 1 : m;
            m = m < 1 ? 1 : m;

            DateTime sdate = new DateTime(y, m, 1);
            DateTime edate = (new DateTime(y, m, 1)).AddMonths(1).AddDays(-1);
            DateTime ysdate = new DateTime(y, 1, 1);
            int sday = GetLocalDay(sdate);
            sdate = sday <= 4 ? sdate.AddDays(1 - sday) : sdate.AddDays(8 - sday);
            int eday = GetLocalDay(edate);
            edate = eday >= 4 ? edate.AddDays(7 - eday) : edate.AddDays(-eday);
            int ysday = GetLocalDay(ysdate);
            ysdate = ysday <= 4 ? ysdate.AddDays(1 - ysday) : ysdate.AddDays(8 - ysday);

            List<WeekDate> lst = new List<WeekDate>();
            while (sdate < edate)
            {
                var week = Math.Floor((decimal)sdate.Subtract(ysdate).Days / 7) + 1;
                WeekDate wd = new WeekDate
                {
                    Week = "Week" + (week < 10 ? "0" + week : week.ToString()),
                    SDate = sdate,
                    EDate = sdate.AddDays(6)
                };
                lst.Add(wd);
                sdate = sdate.AddDays(7);
            }
            var yearMonth = string.Format("{0:yyyy}/{1:MM}", new DateTime(y, m, 1), new DateTime(y, m, 1));
            return new MonthWeek { YearMonth = yearMonth, lstWeeks = lst };
        }
        private static int GetLocalDay(DateTime curDate) => (int)curDate.DayOfWeek == 0 ? 7 : (int)curDate.DayOfWeek;
    }

    public class MonthWeek
    {
        public string YearMonth { get; set; }
        public List<WeekDate> lstWeeks { get; set; }
    }

    public class WeekDate
    {
        public string Week { get; set; }
        public DateTime SDate { get; set; }
        public DateTime EDate { get; set; }
    }
}

确认本月有几周,输出每周开始时间和结束时间(月头和月尾不足7天也输出)

/// <summary>
/// 确认本月有几周,输出每周开始时间和结束时间(月头和月尾不足7天也输出)
/// </summary>
/// <param name="dt"></param>
/// <returns></returns>
public static void NumWeeks(this DateTime dt)
{
    //当前月第一天
    DateTime weekStart = dt.AddDays(1 - dt.Day);
    //该月的最后一天
    DateTime monEnd = weekStart.AddMonths(1).AddDays(-1);
    int i = 1;
    //当前月第一天是星期几
    int dayOfWeek = (int)weekStart.DayOfWeek;
    //该月第一周结束日期
    DateTime weekEnd = dayOfWeek == 0 ? weekStart : weekStart.AddDays(7 - dayOfWeek);

    Console.WriteLine( "第" + i + "周起始日期: " + weekStart.ToShortDateString() + "   结束日期: " + weekEnd.ToShortDateString() + "\n"); 
    //当日期小于或等于该月的最后一天
    while (weekEnd.AddDays(1) <= monEnd)
    {
        i++;
        //该周的开始时间
        weekStart = weekEnd.AddDays(1);
        //该周结束时间
        weekEnd = weekEnd.AddDays(7) > monEnd ? monEnd : weekEnd.AddDays(7);

        Console.WriteLine("第" + i + "周起始日期: " + weekStart.ToShortDateString() + "   结束日期: " + weekEnd.ToShortDateString() + "\n");
    }
}
获取当前日期时间
//获取自定义样式完整时间
//24小时制
DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"); //2019-12-24 02:57:37.149
//12小时制
DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss.fff"); //2019-12-24 02:57:37.149

//获取日期+时间
DateTime.Now.ToString();            // 2008-9-4 20:02:10
DateTime.Now.ToLocalTime().ToString();        // 2008-9-4 20:12:12

//获取日期
DateTime.Now.ToLongDateString().ToString();    // 2008年9月4日
DateTime.Now.ToShortDateString().ToString();    // 2008-9-4
DateTime.Now.ToString("yyyy-MM-dd");        // 2008-09-04
DateTime.Now.Date.ToString();            // 2008-9-4 0:00:00

//获取时间
DateTime.Now.ToLongTimeString().ToString();   // 20:16:16
DateTime.Now.ToShortTimeString().ToString();   // 20:16
DateTime.Now.ToString("HH:mm:ss");        // 08:05:57
DateTime.Now.TimeOfDay.ToString();        // 20:33:50.7187500

//其他
DateTime.ToFileTime().ToString();       // 128650040212500000
DateTime.Now.ToFileTimeUtc().ToString();   // 128650040772968750
DateTime.Now.ToOADate().ToString();       // 39695.8461709606
DateTime.Now.ToUniversalTime().ToString();   // 2008-9-4 12:19:14

DateTime.Now.Year.ToString();         获取年份  // 2008
DateTime.Now.Month.ToString();      获取月份   // 9
DateTime.Now.DayOfWeek.ToString(); 获取星期   // Thursday
DateTime.Now.DayOfYear.ToString(); 获取第几天   // 248
DateTime.Now.Hour.ToString();          获取小时   // 20
DateTime.Now.Minute.ToString();     获取分钟   // 31
DateTime.Now.Second.ToString();     获取秒数   // 45

//n为一个数,可以数整数,也可以事小数
dt.AddYears(n).ToString();   //时间加n年
dt.AddDays(n).ToString();   //加n天
dt.AddHours(n).ToString();   //加n小时
dt.AddMonths(n).ToString();   //加n个月
dt.AddSeconds(n).ToString();   //加n秒
dt.AddMinutes(n).ToString();   //加n分
获取当前程序目录
Environment.CurrentDirectory
System.IO.Directory.GetCurrentDirectory()
System.IO.Path.GetDirectoryName(typeof(Program).Assembly.Location)
AppContext.BaseDirectory

string path = System.Environment.CurrentDirectory;
path = AppDomain.CurrentDomain.BaseDirectory;
path=Directory.GetCurrentDirectory();
//进程exe/dll文件目录
path = Environment.ProcessPath;

//wwwroot目录,没有则为null
var a= builder.Environment.WebRootPath;

//程序目录
var b = builder.Environment.ContentRootPath;

var c =app.Environment.WebRootPath;

var d = app.Environment.ContentRootPath;
获取属性名
//T t = new T();
var instanceOfT = Activator.CreateInstance<T>();
PropertyInfo[] propertyInfos = instanceOfT.GetType().GetProperties();
foreach (PropertyInfo pi in propertyInfos)
{
  Console.WriteLine(pi.Name);
}
Encoding 编码

编码文档

using System.Text;

Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
Console.WriteLine(Encoding.ASCII.CodePage);
Console.WriteLine(Encoding.Unicode.CodePage);
Console.WriteLine(Encoding.UTF8.CodePage);
Console.WriteLine(Encoding.Default.CodePage);
Console.WriteLine(Encoding.GetEncoding("GBK").CodePage);
Console.WriteLine(Encoding.GetEncoding("GB2312").CodePage);
API路由

Controller添加

[Route("api/[controller]/[action]/{id?}")]

或者添加全局路由

自动根据方法匹配路由的Controller不能添加ApiController属性。
如果Controller中有Route属性,还是以Route为主。

app.MapControllerRoute(name: "default", pattern: "api/{controller}/{action}/{id?}");
路由跳转
var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers();
var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.UseDeveloperExceptionPage();
}
else
{
    app.UseExceptionHandler("/Home/Error");
}

app.UseRouting();


--Host和Path之间添加额外字符串
--Net7+
app.UsePathBase("/test1");
app.UsePathBase("/test2");

--Net6
app.UsePathBase("/myapp");
app.UseRouting();


//.net6+
app.MapGet("/", () => "Hello World!");


//.net5及以下版本
app.UseEndpoints(endpoints =>
{
    endpoints.MapControllers();
    //endpoints.Map("/", async context =>
    //{
    //    context.Response.Redirect("/swagger");
    //    await Task.CompletedTask;
    //});
    //endpoints.MapGet("/", async context => await context.Response.WriteAsync("Hello World!"));
});
app.Run();
判断当前环境
  public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            env.IsDevelopment();
            env.IsProduction();
            env.IsStaging();
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
        }
        
Environments.Development
Environments.Staging
Environments.Production

var builder = WebApplication.CreateBuilder(new WebApplicationOptions
{
    Args = args,
    EnvironmentName = Environments.Production
});

var d=builder.Environment.EnvironmentName;
d = app.Environment.EnvironmentName;
Html

解析Html 帮助类

  • AngleSharp
  • HtmlAgilityPack
  • htmlparser
  • MSHTML
  • Jumony
/// <summary>
/// 根据URL返回网页源代码
/// </summary>
/// <param name="url"></param>
/// <returns></returns>
private string GetHttpWebRequest2(string url)
{
	string strHTML = string.Empty;
	//需要Neget 引入 HtmlAgilityPack 程序包
	//strHTML = new HtmlWeb().Load(url).Text;
	//strHTML = new HtmlWeb().Load(url).ParsedText;
	return strHTML;
}
Sql脚本Migrations执行迁移

Nuget安装Evolve

private static Evolve BuildEvolve(IDbConnection cnx)
{
    var evolve = new Evolve((System.Data.Common.DbConnection)cnx, msg => Debug.WriteLine(msg))
    {
        IsEraseDisabled = true,
        // 用于记录数据库版本记录的表,指定表名后,会自动创建
        MetadataTableName = "db_changelogs"
    };
    // 指定数据库脚本所在目录
    var dbPaths = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "db_migrations");
    if (Directory.Exists(dbPaths) && Directory.GetFiles(dbPaths, "*.sql").Length > 0)
    {
        evolve.Locations = new[] { dbPaths };
    }
    else
    {
        // 未找到数据库脚本的逻辑处理,这里可不做任何处理接返回
        evolve.EmbeddedResourceAssemblies = new Assembly[]
        {
            typeof(SqlDbClientContext).Assembly
        };
    }
    return evolve;
}
判断日期是否是法定节假日或者休息日

检查一个日期是否是节假日、工作日、休息日

检查多个日期是否是节假日、工作日、休息日

获取一个月或多个月所有节假日

返回数据:{"201908":{"03":"2","04":"2","10":"1","11":"1","17":"1","18":"2","24":"2","25":"2","31":"1"}},JSON字符串键值:日期/状态码

状态码:工作日对应结果为 0, 休息日对应结果为 1, 节假日对应的结果为 2

获取全年所有节假日

百度接口:(状态1表示节假日,状态2表示周末需要工作的工作日)

  1. https://opendata.baidu.com/api.php?query=2023年1月&resource_id=39043&format=json&tn=wisetpl
  2. https://sp0.baidu.com/8aQDcjqpAAV3otqbppnN2DJv/api.php?tn=wisetpl&resource_id=39043&query=2022年4月
  3. https://sp1.baidu.com/8aQDcjqpAAV3otqbppnN2DJv/api.php?tn=wisetpl&resource_id=39043&query=2022年4月
  4. https://sp2.baidu.com/8aQDcjqpAAV3otqbppnN2DJv/api.php?tn=wisetpl&resource_id=39043&query=2022年4月
  5. https://sp3.baidu.com/8aQDcjqpAAV3otqbppnN2DJv/api.php?tn=wisetpl&resource_id=39043&query=2022年4月
posted @ 2019-12-24 22:01  雨水的命运  阅读(306)  评论(0编辑  收藏  举报