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存档及其文件条目的方法分布在三个类中:ZipFile,ZipArchive和ZipArchiveEntry。
- ZipFile.CreateFromDirectory:从目录创建zip存档。
- ZipFile.ExtractToDirectory:将zip存档的内容提取到目录中。
- ZipArchive.CreateEntry:将新文件添加到现有的zip存档中。
- ZipArchive.GetEntry:从zip存档中检索文件。
- ZipArchive.Entries:从zip存档中检索所有文件。
- ZipArchiveEntry.Open:将流打开到zip存档中包含的单个文件。
- ZipArchiveEntry.Delete:从zip存档中删除文件。
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;
}
判断日期是否是法定节假日或者休息日
检查一个日期是否是节假日、工作日、休息日
- http://www.easybots.cn/api/holiday.php?d=20190913
- http://api.goseek.cn/Tools/holiday?date=20190913
- http://tool.bitefu.net/jiari/?d=20190913
检查多个日期是否是节假日、工作日、休息日
- http://www.easybots.cn/api/holiday.php?d=20190913,20190914,20190915
- http://tool.bitefu.net/jiari/?d=20190913,20190914,20190915
- https://www.cnblogs.com/RainFate/p/11517915.html#_labelTop)
获取一个月或多个月所有节假日
- http://www.easybots.cn/api/holiday.php?m=201908
- http://www.easybots.cn/api/holiday.php?m=201907,201908
返回数据:{"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表示周末需要工作的工作日)
- https://opendata.baidu.com/api.php?query=2023年1月&resource_id=39043&format=json&tn=wisetpl
- https://sp0.baidu.com/8aQDcjqpAAV3otqbppnN2DJv/api.php?tn=wisetpl&resource_id=39043&query=2022年4月
- https://sp1.baidu.com/8aQDcjqpAAV3otqbppnN2DJv/api.php?tn=wisetpl&resource_id=39043&query=2022年4月
- https://sp2.baidu.com/8aQDcjqpAAV3otqbppnN2DJv/api.php?tn=wisetpl&resource_id=39043&query=2022年4月
- https://sp3.baidu.com/8aQDcjqpAAV3otqbppnN2DJv/api.php?tn=wisetpl&resource_id=39043&query=2022年4月