C#常用
字符串
数字字符串互转
- 数字转字符串
string str = num.ToString();
str = num + "";
- 数组转字符串
int[] nums = {1, 2, 3, 4, 5};
string str = string.Join(",", nums);
若对数组使用ToString(),返回的是数组类型的名称,如
strNums = nums.ToString()
输出为
System.Int32[]
。
连接字符串
-
使用+运算符
str = str1 + " " + str2;
-
使用String.Concat()
res = String.Concat(str1, ",", str2)
-
使用StringBuilder类:
StringBuilder sb = new StringBuilder();
sb.Append("Hello");
sb.Append(" ");
sb.Append("World");
string result = sb.ToString();
使用StringBuilder类在连接大量字符串时效率更高,因为可以避免每次连接都创建一个新的字符串对象。
使用特定分隔符将数组连接成字符串 string.Join(',', List<string>)
使用Concat方法可以将两个数组连接起来: 创建了一个新数组,其中包含两个原始数组的元素。
int[] arr1 = {1,2,3}
int[] arr2 = {4,5,6}
int[] concatArr = arr1.Concat(arr2).ToArray();
字符串插值
int x = 5;
int y = 10;
string result = $"The sum of {x} and {y} is {x + y}.";
使用@符号的字符串插值:
string name = "Alice";
int age = 25;
string sentence = $@"My name is {name} and I am {age} years old.";
使用 @ 符号的字符串插值可以避免在字符串中使用转义字符。
StringBuilder
加换行
在StringBuilder中加换行,使用Environment.NewLine
或者\n
。
StringBuilder sb = new StringBuilder();
sb.Append("1");
sb.Append("Environment.NewLine"); //或"\n"
sb.Append("2");
删除StringBuilder的最后一个字符
- 使用StringBuilder.Remove()方法
StringBuilder sb = new StringBuilder("Hello World!");
sb.Remove(sb.Length - 1, 1); // 指定要删除的起始位置和长度
- 使用StringBuilder.Length属性
sb.Length--; // 如果StringBuilder对象为空,会引发ArgumentOutOfRangeException异常
- 使用StringBuilder.Chars属性
可以通过将StringBuilder.Chars[sb.Length-1]的值设置为\0
实现。使用该方法只能删除字符,不能删除字符串的任意字串。
桩号转换
C#方法
string mileStr = "K" + mile.toString("0.000").replace(".", "+");
Js方法
let mileStr = 'K' + v.toFixed(3).replace('.', '+');
判断一个字符串中包含的是数字还是其他字符
使用int.TryParse()
方法来尝试将字符串转换为整数。如果转换成功,则说明字符串中包含的是数字;如果转换失败,则说明字符串中包含的是其他字符。
string input = "12345";
int number;
if (int.TryParse(input, out number))
{
Console.WriteLine("字符串中包含的是数字");
}
else
{
Console.WriteLine("字符串中包含的是其他字符");
}
解析URL查询字符串
使用HttpUtility.ParseQueryString
方法来解析URL查询字符串,并提取出所有的对象和值。
using System;
using System.Collections.Specialized;
class Program
{
static void Main()
{
string queryString = "showType=2&redundanceType=1&selectAllFlag=false";
// 解析查询字符串
NameValueCollection queryParams = System.Web.HttpUtility.ParseQueryString(queryString);
// 遍历提取的对象和值
foreach (string key in queryParams.AllKeys)
{
string value = queryParams[key];
Console.WriteLine("对象:{0},值:{1}", key, value);
}
}
}
注意,上述示例中使用了System.Web.HttpUtility.ParseQueryString
方法,因此需要确保项目引用了System.Web
命名空间。如果是在.NET Core项目中,可以使用Microsoft.AspNetCore.WebUtilities.QueryHelpers.ParseQuery
方法来解析查询字符串。
对象拷贝
浅拷贝vs深拷贝:
- 浅拷贝指对象中的值类型字段拷贝到新对象中,引用类型复制一个引用到目标对象。
- 深拷贝不仅复制对象值类型,也复制对象,相当于创建了一个新对象,将当前对象的多有字段进行逐位复制并支持递归(不管值类型还是引用类型,不管静态字段还是非静态字段)。
注:string类型浅拷贝作值类型对象处理。
浅拷贝
使用Object类MemberwiseClone:创建当前Object的浅表副本。
public class Person{
public int Age {get; set;}
public string Name {get; set;}
public OtherAttr Other {get; set;}
public object Clone(){
return this.MemberwiseClone();
}
}
赋值操作(=)vs使用MemberwiseClone:浅拷贝对引用类型中的值类型字段进行了逐位复制,赋值运算符只是把源对象的引用赋值给目的对象。浅拷贝后对象的值类型字段更改不影响源对象,而赋值运算符会。
深拷贝
- 实现ICloneable接口,自定义拷贝功能。ICloneable接口包含一个成员Clone。
public class Person: ICloneable{
public int Age {get; set;}
public string Name {get; set;}
public OtherAttr Other {get; set;}
public object Clone(){
Person tem = new Person();
tem.Age = this.Age;
tem.Name = this.Name;
tem.Name = this.Name;
tem.Other = new OtherAttr(this.Other);
return tem;
}
}
- 反射机制实现
public static T DeepCopyByReflection<T>(T obj){
if(obj is string || obj.GetType().IsValueType){
return obj;
}
object val = Activator.CreateInstance(obj.GetType());
FieldInfo[] fields = obj.GetType().GetFields();
foreach(var field in fields){
try{
field.SetValue(val, DeepCopyByReflection(field.GetValue(obj)));
}
catch{}
}
return (T)val;
}
- 序列化/反序列化实现
- 序列化是将对象或对象图形转换为线性字节序列,以存储或传输到另一个位置的过程。
- 反序列化是接受存储的信息并利用它重新创建对象的过程。
使用序列化和反序列化,需要标记可序列化类型,即添加特性(Attribute)[Serializable]。
public static T DeepCopyByBinary<T>(T obj){
object val;
using(MemoryStream ms = new MemoryStream()){
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(ms, obj);
ms.Seek(0, SeekOrigin.Begin);
val = bf.Deserialize(ms);
ms.Close();
}
return (T)val;
}
- DataSet的两个方法对比:Clone vs Copy
- Clone:复制DataSet的架构、关系、约束,不复制数据。
- Copy:复制DataSet的结构和数据。
利用itextSharp实现pdf合并
public static void Main(string[] args)
{
string[] pdfFiles = { @"合并导出202306270211.pdf", @"合并导出202306270251.pdf" }; // 要合并的 PDF 文件路径
string outputFile = @"C:\Users\10051\Desktop\merged.pdf"; // 合并后的输出文件路径
MergePdfFiles(pdfFiles, outputFile);
Console.WriteLine("PDF files merged successfully!");
}
public static void MergePdfFiles(string[] pdfFiles, string outputFile)
{
using (FileStream stream = new FileStream(outputFile, FileMode.Create))
{
Document document = new Document();
PdfCopy pdf = new PdfCopy(document, stream);
document.Open();
foreach (string file in pdfFiles)
{
PdfReader reader = new PdfReader(file);
for (int i = 1; i <= reader.NumberOfPages; i++)
{
PdfImportedPage page = pdf.GetImportedPage(reader, i);
pdf.AddPage(page);
}
reader.Close();
}
document.Close();
}
}
LINQ
排序方法
-
使用Sort降序排序
nodes.Sort((b, a)=>{return a.Cost.ComperaTo(b.Cost);})
CompareTo 方法返回一个整数,表示两个对象的相对顺序。返回值的含义如下:
- 如果调用对象小于传入对象,则返回一个负数(通常是 -1)。
- 如果调用对象等于传入对象,则返回 0。
- 如果调用对象大于传入对象,则返回一个正数(通常是 1)。
//重写排序:
class Obj{
public int rank = 0;
public string word = null;
}
public static int MySort(Obj A, Obj B){
return B.rank.CompareTo(A.rank);
}
List<Obj> lst = new List<Obj>();
lst.Sort(MySort);
- 使用LINQ排序
//LINQ方法语法:
int[] numbers = { 5, 2, 8, 1, 9 };
var sortedNumbers = numbers.OrderBy(num => num);
//LINQ查询语法:
var sortedNumbers = from num in numbers
orderby num ascending
select num;
//对字典排序重组
Dictionary<int, string> paths = new Dictionary<int, string>(){
{1,"test1"},
{3,"test5"},
{2,"test6"}
}
string[] sortedArr = paths.OrderBy(pair => pair.Key).Select(pair => pair.Value).ToArray();
相减操作(使用查询表达式或方法语法)
- 使用查询表达式:
var result = from num1 in numbers1
from num2 in numbers2
select num1 - num2;
- 使用方法语法:
var result = numbers1.SelectMany(num1 => numbers2, (num1, num2) => num1 - num2);
筛选
- 使用 LINQ 的
TakeWhile
方法来筛选出满足条件的项,直到遇到不满足条件的项为止。
var sum = list
.TakeWhile(item => item.Name != 400)
.Sum(item => item.Name);
TakeWhile
方法会从列表中取出满足条件的项,直到遇到 Name
属性为 400 的项为止。然后,Sum
方法用于对这些项的 Name
属性进行求和。
- 筛选并合计
var result = list
.TakeWhile(item => item.Name != 400)
.Aggregate(
new { Name = "", Sum = 0, Count = 0 },
(acc, item) => new
{
Name = item.Name,
Sum = acc.Sum + item.Name,
Count = acc.Count + 1
}
);
TakeWhile
方法用于从列表中取出满足条件的项,直到遇到 Name
属性为 400 的项为止。然后,Aggregate
方法用于对这些项进行累积计算,初始值为一个匿名类型对象 { Name = "", Sum = 0, Count = 0 }
。在每次迭代中,累加器 acc
的 Sum
属性和 Count
属性会根据当前项的 Name
属性进行更新。最终,结果会存储在 result
变量中,其中包含了 Name
、Sum
和 Count
三个属性。
- 前几项合计
使用 Take
方法来获取前5项,然后使用 Aggregate
方法对这些项进行累加计算。
var result = list
.Take(5)
.Aggregate(
new { Name = "", Sum = 0 },
(acc, item) => new
{
Name = item.Name,
Sum = acc.Sum + item.Sum
}
);
- 后几项合计
使用 Skip
方法来跳过前4项,然后使用 Aggregate
方法对剩余的项进行累加计算。
var result = list
.Skip(4)
.Aggregate(
new { Name = "", Sum = 0 },
(acc, item) => new
{
Name = item.Name,
Sum = acc.Sum + item.Sum
}
);
多行某字段的字符串拼接
使用GroupBy
和String.Join
方法来实现将组内的所有status
字段拼接
var result = yourList
.GroupBy(x => new { x.TableName, x.Param })
.Select(g => new {
TableName = g.Key.TableName,
Param = g.Key.Param,
StatusStr = string.Join(",", g.Select(x => x.Status.ToString()))
});
正则表达式
使用正则表达式提取所有数字 (\d+)
using System;
using System.Text.RegularExpressions;
public class Program
{
public static void Main(string[] args)
{
string input = "abc123def456ghi789";
MatchCollection matches = Regex.Matches(input, @"\d+");
foreach(Match match in matches)
{
Console.WriteLine(match.Value);
}
}
}
其他
关于DataColumn使用decimal类型
在 C# 中,DataColumn
的类型为 decimal
时,其值不能为 null
。decimal
是一个值类型(Value Type),它表示一个精确的十进制数。值类型在声明时会有一个默认值,对于 decimal
类型,默认值为 0
。
如果你需要在 DataColumn
中存储可空的 decimal
值,可以使用 Nullable<decimal>;
或者 decimal?
来声明该列的类型。这样就可以在 DataColumn
中存储 null
值。例如:
DataColumn column = new DataColumn("ColumnName", typeof(decimal?));
或者:
DataColumn column = new DataColumn("ColumnName", typeof(Nullable\<decimal>));
使用可空类型 decimal?
或者 Nullable<decimal>;
可以在需要时将 DataColumn
的值设置为 null
。这在某些情况下非常有用,例如当某些数据项的值未知或不适用时。
判断对象的方法是否存在并调用该方法
public void ProcessObjectByName(string objectName)
{
Type objectType = Type.GetType(objectName);
if (objectType != null)
{
object obj = Activator.CreateInstance(objectType);
MethodInfo processMethod = objectType.GetMethod("Process");
if (processMethod != null)
{
// 判断方法是否可调用
if (processMethod.IsPublic && !processMethod.IsStatic)
{
processMethod.Invoke(obj, null);
}
else
{
Console.WriteLine("Method is not accessible or static.");
}
}
else
{
Console.WriteLine("Method does not exist.");
}
}
else
{
Console.WriteLine("Type does not exist.");
}
}
首先通过Type.GetType
方法根据拼接的对象名获取到对象的Type
。然后使用Activator.CreateInstance
方法创建一个对象实例。
接下来,使用GetMethod
方法获取到对象的Process
方法的MethodInfo
对象。然后通过IsPublic
和IsStatic
属性判断方法是否可调用。
如果方法可调用,则使用Invoke
方法调用该方法。否则,打印相应的错误信息。
可以在调用ProcessObjectByName
方法时,传入拼接的对象名作为参数。然后在方法内部,通过反射获取到对应的对象,并判断其Process
方法是否存在和可调用。
一对多实现
使用 Dictionary<TKey, List<TValue>>
来实现一对多的字典对象。其中,TKey
是键的类型,TValue
是值的类型。
using System;
using System.Collections.Generic;
class Program
{
static void Main(string[] args)
{
// 创建一个一对多的字典对象
Dictionary<string, List<string>> dictionary = new Dictionary<string, List<string>>();
// 添加键值对
AddKeyValuePair(dictionary, "Key1", "Value1");
AddKeyValuePair(dictionary, "Key1", "Value2");
AddKeyValuePair(dictionary, "Key2", "Value3");
AddKeyValuePair(dictionary, "Key2", "Value4");
// 输出字典对象的内容
foreach (var kvp in dictionary)
{
string key = kvp.Key;
List<string> values = kvp.Value;
Console.WriteLine($"Key: {key}");
Console.WriteLine("Values:");
foreach (string value in values)
{
Console.WriteLine(value);
}
Console.WriteLine();
}
}
static void AddKeyValuePair(Dictionary<string, List<string>> dictionary, string key, string value)
{
// 如果字典中已存在该键,则将值添加到对应的列表中
if (dictionary.ContainsKey(key))
{
dictionary[key].Add(value);
}
// 如果字典中不存在该键,则创建一个新的列表,并将值添加到列表中
else
{
List<string> values = new List<string> { value };
dictionary.Add(key, values);
}
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· AI与.NET技术实操系列(六):基于图像分类模型对图像进行分类