Skip to main content

Command Palette

Search for a command to run...

c# string-basics

Updated
2 min read
E

Science is gold.

formatting

  1. 设置货币格式

    :C 货币格式说明符用于将变量以货币形式显示

     Console.WriteLine($"Price:{price:C}")
     decimal price = 123.45m;
     int discount = 50;
     Console.WriteLine($"Price: {price:C} (Save {discount:C})");
    
     // Output:
     // Price: $123.45 (Save $50.00)
    

    请注意,无论使用 int 还是 decimal,在大括号内的标记中添加 :C 都会将数字格式化为货币。

  2. 设置数值格式

    N 数值格式说明符使数字更具可读性。

decimal measurement = 123456.78912m;
Console.WriteLine($"Measurement: {measurement:N} units");

// output:
// Measurement: 123,456.79 units

N 数值格式说明符默认仅显示小数点后两位数字。如果要以更高的精度显示,可通过在说明符后面添加数字来实现。

decimal measurement = 123456.78912m;
Console.WriteLine($"Measurement: {measurement:N4} units");

// output:
// Measurement: 123,456.7891 units
  1. 设置百分比的格式

    使用 P 格式说明符设置百分比的格式。

decimal tax = .36785m;
Console.WriteLine($"Tax rate: {tax:P2}");

// output:
// Tax rate: 36.79 %
  1. 添加空白进行格式设置的方法(PadLeft()PadRight()

  2. 比较两个字符串或辅助比较的方法(Trim()TrimStart()TrimEnd()GetHashcode()Length 属性)

  3. 帮助确定字符串内部内容,甚至只检索部分字符串的方法(Contains()StartsWith()EndsWith()Substring()

  4. 通过替换、插入或删除部件来更改字符串内容的方法(Replace()Insert()Remove()

  5. 将字符串转换为字符串或字符数组的方法(Split()ToCharArray()

modify-content

  1. 避免 magic 值

    避免硬编码的 magic 值。 改为定义 const 变量。 初始化后,常数变量的值无法更改。

string message = "What is the value <span>between the tags</span>?";

int openingPosition = message.IndexOf("<span>");
int closingPosition = message.IndexOf("</span>");

openingPosition += 6;
int length = closingPosition - openingPosition;
Console.WriteLine(message.Substring(openingPosition, length));

在前面的代码中,像 "<span>" 这样的硬编码字符串称作“magic 字符串”,而像 6 这样的硬编码数值称作“幻数”。 由于多种原因,你并不需要这些“magic”值,因此应尽量避免使用它们。

如果你在代码中多次对字符串 "<span>" 进行了硬编码,但将其中一个实例误拼为 "<sapn>"。或者将字符串 "<span>" 更改为 "<div>",但忘记更改数字 6,则代码将产生非预期结果。

string message = "What is the value <span>between the tags</span>?";

const string openSpan = "<span>";
const string closeSpan = "</span>";

int openingPosition = message.IndexOf(openSpan);
int closingPosition = message.IndexOf(closeSpan);

openingPosition += openSpan.Length;
int length = closingPosition - openingPosition;
Console.WriteLine(message.Substring(openingPosition, length));
  1. IndexOfAny 和 LastIndexOf

    • LastIndexOf() 返回字符或字符串在另一个字符串中最后出现的位置。

    • IndexOfAny() 返回在另一个字符串内首次出现 char 数组的位置。

    string message = "(What if) I have [different symbols] but every {open symbol} needs a [matching closing symbol]?";

    // The IndexOfAny() helper method requires a char array of characters. 
    // You want to look for:

    char[] openSymbols = { '[', '{', '(' };

    // You'll use a slightly different technique for iterating through 
    // the characters in the string. This time, use the closing 
    // position of the previous iteration as the starting index for the 
    //next open symbol. So, you need to initialize the closingPosition 
    // variable to zero:

    int closingPosition = 0;

    while (true)
    {
        int openingPosition = message.IndexOfAny(openSymbols, closingPosition);

        if (openingPosition == -1) break;

        string currentSymbol = message.Substring(openingPosition, 1);

        // Now  find the matching closing symbol
        char matchingSymbol = ' ';

        switch (currentSymbol)
        {
            case "[":
                matchingSymbol = ']';
                break;
            case "{":
                matchingSymbol = '}';
                break;
            case "(":
                matchingSymbol = ')';
                break;
        }

        // To find the closingPosition, use an overload of the IndexOf method to specify 
        // that the search for the matchingSymbol should start at the openingPosition in the string. 

        openingPosition += 1;
        closingPosition = message.IndexOf(matchingSymbol, openingPosition);

        // Finally, use the techniques you've already learned to display the sub-string:

        int length = closingPosition - openingPosition;
        Console.WriteLine(message.Substring(openingPosition, length));
    }
    // 输出:
    What if
    different symbols
    open symbol
    matching closing symbol

More from this blog

C# 标准性能测试高级用法(Benchmark)

在 C# 标准性能测试 已经告诉大家如何使用 BenchmarkDotNet 测试性能,本文会告诉大家高级的用法。 建议是创建一个控制台项目用来做性能测试,这个项目要求是 dotnet framework 4.6 以上,建议是 dotnet 7 的版本。使用这个项目引用需要测试的项目,然后在里面写测试的代码。 例如被测试项目有一个类 Foo 里面有一个叫 Lindexidb 的方法,接下来的任务是需要测试这个 Lindexidb 方法的性能 最简单的测试的代码 public class FooP...

Jan 9, 20247 min read

.NetCore 实践——HttpClientFactory[一]

HttpClientFactory介绍 HttpClientFactory 主要有下面的功能: 管理内部HttpMessageHandler 的生命周期,灵活应对资源问题和DNS刷新问题 支持命名话、类型化配置,集中管理配置,避免冲突。 灵活的出站请求管道配置,轻松管理请求生命周期 内置管道最外层和最内层日志记录器,有information 和 Trace 输出 核心对象: HttpClient HttpMessageHandler SocketsHttpHandler De...

Jan 9, 20245 min read

认识 MSBuild - 1

前言 很多人一谈到 MSBuild,脑子里就会出现 “XML”、“只能用 VS 的属性框图形界面操作”、“可定制性和扩展性差” 和 “性能低” 等印象,但实际上这些除了 “XML” 之外完全都是刻板印象:这些人用着 Visual Studio 提供的图形界面,就完全不愿意花个几分钟时间翻翻文档去理解 MSBuild 及其构建过程。 另外,再加上 vcxproj (Visual C++ 项目)的默认 MSBuild 构建文件写得确实谈不上好(默认只能项目粒度并行编译,想要源码级并行编译你得加钱),...

Jan 9, 20245 min read

.NetCore实战——工作单元模式(UnitOfWork):管理好你的事务

工作单元模式有如下几个特性: 1、使用同一上下文 2、跟踪实体的状态 3、保障事务一致性 我们对实体的操作,最终的状态都是应该如实保存到我们的存储中,进行持久化 接下来看一下代码 为了实现工作单元模式,这里定义了一个工作单元的接口 public interface IUnitOfWork : IDisposable { Task<int> SaveChangesAsync(CancellationToken cancellationToken = default); Task<b...

Jan 9, 20242 min read
E

Edward Chu's blog

41 posts