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[]

连接字符串

  1. 使用+运算符

    str = str1 + " " + str2;

  2. 使用String.Concat()

    res = String.Concat(str1, ",", str2)

  3. 使用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的最后一个字符

  1. 使用StringBuilder.Remove()方法
StringBuilder sb = new StringBuilder("Hello World!");
sb.Remove(sb.Length - 1, 1);  // 指定要删除的起始位置和长度 
  1. 使用StringBuilder.Length属性
sb.Length--;  // 如果StringBuilder对象为空,会引发ArgumentOutOfRangeException异常
  1. 使用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:浅拷贝对引用类型中的值类型字段进行了逐位复制,赋值运算符只是把源对象的引用赋值给目的对象。浅拷贝后对象的值类型字段更改不影响源对象,而赋值运算符会。

深拷贝

  1. 实现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;
    }
}
  1. 反射机制实现
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;
}
  1. 序列化/反序列化实现
  • 序列化是将对象或对象图形转换为线性字节序列,以存储或传输到另一个位置的过程。
  • 反序列化是接受存储的信息并利用它重新创建对象的过程。
    使用序列化和反序列化,需要标记可序列化类型,即添加特性(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

排序方法

  1. 使用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);
  1. 使用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();

相减操作(使用查询表达式或方法语法)

  1. 使用查询表达式:
var result = from num1 in numbers1  
             from num2 in numbers2  
             select num1 - num2;  
  1. 使用方法语法:
var result = numbers1.SelectMany(num1 =&gt; numbers2, (num1, num2) =&gt; num1 - num2);  

筛选

  1. 使用 LINQ 的 TakeWhile 方法来筛选出满足条件的项,直到遇到不满足条件的项为止。
var sum = list
    .TakeWhile(item => item.Name != 400)
    .Sum(item => item.Name);

TakeWhile 方法会从列表中取出满足条件的项,直到遇到 Name 属性为 400 的项为止。然后,Sum 方法用于对这些项的 Name 属性进行求和。

  1. 筛选并合计
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 }。在每次迭代中,累加器 accSum 属性和 Count 属性会根据当前项的 Name 属性进行更新。最终,结果会存储在 result 变量中,其中包含了 NameSumCount 三个属性。

  1. 前几项合计

使用 Take 方法来获取前5项,然后使用 Aggregate 方法对这些项进行累加计算。

var result = list
    .Take(5)
    .Aggregate(
        new { Name = "", Sum = 0 },
        (acc, item) => new
        {
            Name = item.Name,
            Sum = acc.Sum + item.Sum
        }
    );
  1. 后几项合计

使用 Skip 方法来跳过前4项,然后使用 Aggregate 方法对剩余的项进行累加计算。

var result = list
    .Skip(4)
    .Aggregate(
        new { Name = "", Sum = 0 },
        (acc, item) => new
        {
            Name = item.Name,
            Sum = acc.Sum + item.Sum
        }
    );

多行某字段的字符串拼接

使用GroupByString.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 时,其值不能为 nulldecimal 是一个值类型(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&gt;));  

使用可空类型 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对象。然后通过IsPublicIsStatic属性判断方法是否可调用。

如果方法可调用,则使用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);
        }
    }
}
posted @   jusaka_m  阅读(32)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· AI与.NET技术实操系列(六):基于图像分类模型对图像进行分类
点击右上角即可分享
微信分享提示

目录在这里