『飞鸽』彻底学通string.Format以及IFormattable,IFormatProvider,ICustomFormatter

labview汽车电子通用测试程序架构,CAN通讯上位机 结合做过的汽车电子测试项目,车身控制器测试,CAN网络模块测试,电机控制器功能测试,汽车仪表盘视觉及功能测试、电气盒功能测试、EOL下线检测、车用空调控制器功能测试等项目,结合实际项目,整理编写的一个汽车电子,通用测试架构,包含项目的讲解等。6、数据保存 、数据处理、 曲线显示 、报警处理等。7、CAN总线故障信息监控及记录保存。2、参数设置(CAN端口及参数)5、CAN通讯+数据解析。 阅读详情

彻底学通string.Format以及IFormattable,IFormatProvider,ICustomFormatter

  自从使用.net以来就一直都在使用string.Format方法,一直没有空或者其他原因都没有深入去了解,主要还是因为项目上似乎没有这么高的要求,也没必要去深入了解,就算碰到了自定义的格式化内容也是写几个通用的方法而已。今天空下来仔细去理解了一下,在这里和大家分享一下,也希望大家一起交流。

 

string.Format方法是string类提供的静态方法,一般最多使用的是其两个参数的重载,例如:

 

var name = "Zhezhe";
var msg = string.Format("Hello Cnblogs, I am {0},Today is {1:yyyy-MM-dd} {2}.", name, DateTime.Now, DateTime.Now.DayOfWeek);
Console.WriteLine(msg);

 

后面一个参数是.net语法简写的可变参数,在.net内部实际是数组而已,实质还是两个参数的方法重载。

你也可以不使用这种方法,将字符串相加即可

var msg1 = "Hello Cnblogs, I am " + name + ",Today is " + DateTime.Now.ToString("yyyy-MM-dd") + " " + DateTime.Now.DayOfWeek + ".";
上面两种方法的结果是一样的。


 之前普遍使用第一种方法的原因是相比string的多个加号相加在性能上有一定优势,因为其内部是使用StringBuilder类的,还有一个原因是代码的可读性比起+这样的方式更好一些。


 

分析一下第一种方法的实现原理:


 1.Format方法的内部解析方式和原理


Format方法在取到第一个参数"Hello Cnblogs, I am {0},Today is {1:yyyy-MM-dd} {2}."之后便将其分解成多个部分

① "Hello Cnblogs, I am "   ② "{0}"  ③",Today is " ④"{1:yyyy-MM-dd}"⑤ "  " ⑥ "{2}"⑦ "."


分解的原则是按照{}配对的数量进行的,{}是微软定义好的标记而已,你自己也可以去实现个用 []表示都无所谓。既然{}已经被定义为了特殊的标记,所以如果是自己需要在字符串中包含大括号的话就必须进行转义,这个转义也和我们平时使用的"/"转义表示法不同,需要使用两个大括号进行转义如 {{ 或者 }}。 如:


 var msg2 = string.Format("Hello {{}},I am {0}", name);
将{}分解出来之后根据中间的序号来对应第二个参数,如果第二个参数的实际个数小于需要的数量,则会出现运行错误(编译时不会报错), 如果参数个数大于序号的数量,则其后的忽略不计。


 参数个数小于序号的实际数量,错误

var msg4 = string.Format("Hello Cnblogs, I am {0},Today is {1:yyyy-MM-dd} {2}.", name, DateTime.Now);
参数个数大于序号的实际数量,多出的参数忽略不计


 var msg4 = string.Format("Hello Cnblogs, I am {0},Today is {1:yyyy-MM-dd}.", name, DateTime.Now,DateTime.Now.DayOfWeek);
序号的顺序不一定必须是0,1,2,3,4可以任意排列,但是序号永远和第二个参数(实质是数组)的索引一致。


var msg4 = string.Format("Hello Cnblogs, I am {2},Today is {0:yyyy-MM-dd} {1}.", DateTime.Now, DateTime.Now.DayOfWeek, name);
序号还能跳跃,但是中间跳跃过的序号参数里必须有


var msg5 = string.Format("Hello Cnblogs, I am {0},Today is {2:yyyy-MM-dd} {3}.", name, "test", DateTime.Now, DateTime.Now.DayOfWeek);
 上面讲了一下用法,接下来继续

分解完毕之后使用 StringBuilder的Append方法将各个部分添加进去,最后再用ToString方法转成string,其实现原理非常类似于下面的代码

var s = new StringBuilder();
            s.Append("Hello Cnblogs, I am ");
            s.Append(name);
            s.Append(",Today is ");
            s.Append(DateTime.Now.ToString("yyyy-MM-dd"));
            s.Append(" ");
            s.Append(DateTime.Now.DayOfWeek);
            s.Append(".");
            var msg3 = s.ToString();
顺便解释一下string和StringBuilder:string虽然也是引用类型,但是该类型.net内部进行了特殊处理,让其表现出和值类型相似的特征,特别是在每次变动之后就会重新分配内存空间,而StringBuilder就不会,所以如果有很多个字符串相加拼接,则string性能较低。


在用 Append方法进行添加的时候会有两种情况:


一种是{0},{1}这样的不带有特殊格式化的则直接会调用该对象的ToString方法,比如上面的  s.Append(DateTime.Now.DayOfWeek);其实就是 s.Append(DateTime.Now.DayOfWeek.ToString());在.net中,如果是自己定义的类,并且没有重写ToString方法,则会输出类的全名,下面会详细讨论。

另一种是{0:yyyy-MM-dd}带有特殊格式化的则继续分解,将冒号后面的内容分解出来,并且在调用ToString时作为参数传入,上面的s.Append(DateTime.Now.ToString("yyyy-MM-dd"));就体现了这一点。所以这些其实都没什么奥妙可言,冒号也是一个预定义好的标记而已,如果微软让你去实现这个,你也可以用其他符号。


 


2.ToString方法的深入理解


通过第一步的分析如果纯粹从分析Format这个方法来说已经足够了,大括号的特殊标记作用以及和后面参数的对应关系也已经解释清楚了。但是这里还是需要深入了解一下ToString方法。

上面1中提到如果一个自己定义的类不去重写ToString方法的话则会 输出类的全名,例如


public class Person
    {
        public string Name { get; set; }
    }
如果写如下代码


var msg6 = string.Format("Hello Cnblogs, I am {0},Today is {1:yyyy-MM-dd} {2}.",
                                     new Person() {Name = "Zhezhe"}, DateTime.Now, DateTime.Now.DayOfWeek);
            Console.WriteLine(msg6);
则会输出:


 这里再次强调一下,如果某个对象需要转换成ToString,并且没有手动调用该方法,程序会自动调用该方法,上面的new Person() {Name = "Zhezhe"}没有手工调用,程序会自动调用方法(new Person() {Name = "Zhezhe"}).ToString(); 这个是微软让你少些代码而已,好的习惯是始终写上 .ToString();

.net中的任何对象都具有该方法,因为该方法在object对象中定义,任何类或者结构都会继承object,所以不用担心一个对象没有ToString方法。

接下来定义带有ToString重载方法的类

public class PersonWithToString
    {
        public string Name { get; set; }

        public override string ToString()
        {
            return Name;
        }
    }
编写如下代码:


 //使用自己定义类,但是重写了ToString方法
var msg7 = string.Format("Hello Cnblogs, I am {0},Today is {1:yyyy-MM-dd} {2}.", new PersonWithToString(){ Name = "Zhezhe" }, DateTime.Now, DateTime.Now.DayOfWeek);
Console.WriteLine(msg7);
输入结果为 输出就正常了,自己重写的方法起作用了。


总结:对自己定义的类始终重写 ToString方法。 这样在 string.Format 中或者其他需要程序自动转换成string类型时不会出现 输出类全名的情况。


 

3.ToString带有自定义格式化参数的理解


上面讲到的ToString都是不带格式化参数的,像  {1:yyyy-MM-dd} 这样的情况是没法处理的,也许有人会说像 DateTime.Now.ToString("yyyy-MM-dd") 这样的情况自己去重载一个ToString方法就可以了,果真如此吗? 下面就测试一下


public class PersonWithToString
    {
        public string Name { get; set; }

        public override string ToString()
        {
            return Name;
        }

        public string ToString(string format)
        {
            switch (format)
            {
                case "UPP":
                    return Name.ToUpper();
                case "LOW":
                    return Name.ToLower();
                default:
                    return Name;
            }
        }
    }

 

var msg9 = string.Format("Hello Cnblogs, I am {0},Today is {1:yyyy-MM-dd} {2}.",
                                  new PersonWithToString() { Name = "Zhezhe" }.ToString("UPP"), DateTime.Now, DateTime.Now.DayOfWeek);
            Console.WriteLine(msg9);
msg9的实际输出为 Hello Cnblogs, I am ZHEZHE,Today is 2010-07-30 Friday.  这个正是我们需要的,当然,这个肯定是对的,要不然就是.net的bug了


接下来再看看下面的

var msg8 = string.Format("Hello Cnblogs, I am {0:UPP},Today is {1:yyyy-MM-dd} {2}.",
                                  new PersonWithToString() { Name = "Zhezhe" }, DateTime.Now, DateTime.Now.DayOfWeek);

实际输出是: Hello Cnblogs, I am Zhezhe,Today is 2010-07-30 Friday.  并不是我们所期望的。实际上上面的代码是调用了PersonWithToString类的不带参数的ToString()方法。言外之意就是   {0:UPP}这样的格式实际上内部处理的是和  {0}

一样的效果了。在1中提到了分解的原理用了类似两个字,实际情况并不是这么简单。

   {0:UPP} 真正调用的方法签名是    string ToString(string format,IFormatProvider formatProvider)

而且也不是直接调用该对象的此方法。而是通过 IFormattable 接口实现的方法

 现在定义实现了该接口的 Person2类

 

Person2
public class Person2 : IFormattable
    {
        public string Name { get; set; }

        public override string ToString()
        {
            return Name;
        }

        #region IFormattable Members

        public string ToString(string format, IFormatProvider formatProvider)
        {
            if (string.IsNullOrEmpty(format))
                return ToString();

            switch (format)
            {
                case "UPP":
                    return Name.ToUpper();
                case "LOW":
                    return Name.ToLower();
                default:
                    return Name;
            }
        }

        #endregion
    }
 运行一下代码得到预期的结果

  //使用实现了IFormattable接口的Person2对象
var msg10 = string.Format("Hello Cnblogs, I am {0:UPP},Today is {1:yyyy-MM-dd} {2}.",
new Person2() { Name = "ZhezheToUpper" }, DateTime.Now, DateTime.Now.DayOfWeek);
Console.WriteLine(msg10);
 ZhezheToUpper已经输出成全部大写形式了。

 

既然{0:UPP}会调用接口定义的ToString方法,那么{0}呢? 如果该类没有实现IFormattable接口,上面已经说了,会调用重载的或者是基类的ToString()方法。但是如果该类已经实现了IFormattable接口,那么{0}也不会去调用重载的或者是基类的ToString()方法了,它始终是去调用 接口定义的 ToString方法。下面具体印证一下

 

Person3
 public class Person3 : IFormattable
    {
        public string Name { get; set; }

        public override string ToString()
        {
            return Name;
        }

        #region IFormattable Members

        public string ToString(string format, IFormatProvider formatProvider)
        {
            if (string.IsNullOrEmpty(format))
                return Name + " IFormattable Method";

            switch (format)
            {
                case "UPP":
                    return Name.ToUpper();
                case "LOW":
                    return Name.ToLower();
                default:
                    return Name + " IFormattable Method";
            }
        }

        #endregion
    }
 

运行下面的测试代码

var msg11 = string.Format("Hello Cnblogs, I am {0},Today is {1:yyyy-MM-dd} {2}.",
                                  new Person3() { Name = "ZhezheToUpper" }, DateTime.Now, DateTime.Now.DayOfWeek);
            Console.WriteLine(msg11);
 

输出为: Hello Cnblogs, I am ZhezheToUpper IFormattable Method,Today is 2010-07-30 Friday.

证明了确实是调用了接口定义的方法,而不是重载的ToString方法,否则是输出ZhezheToUpper

再来看一下Person2中实现的ToString方法,

 if (string.IsNullOrEmpty(format))
                return ToString();
如果是刚才的{0}不带格式化参数的调用,则format参数传过来的是null值,这里需要自己判断,如果是null值,一般情况下是手工去调用重载的ToString()方法。
所以Person2的做法是好的,而Person3中的做法是不好的,Person3只是为了测试分辨出调用的是哪个方法才这么设计的。

 

总结:一.对于实现IFormattable 接口时,如果format参数为null(即不带格式化参数的情况,如{0})则应该调用重载的 ToString()方法,而不应该自己去另外写代码。

二.如果找不到相应的格式化参数,例如{0:AAA},在Person2的switch中并无匹配的AAA,这种情况一般也应该去调用重载的 ToString()方法。

否则就会出现


 //以下两个输出结果不一样,是不合理的
var msg12 = string.Format("Hello Cnblogs, I am {0},Today is {1:yyyy-MM-dd} {2}.",new Person3() { Name = "ZhezheToUpper" }, DateTime.Now, DateTime.Now.DayOfWeek);
Console.WriteLine(msg12);

var msg13 = string.Format("Hello Cnblogs, I am {0},Today is {1:yyyy-MM-dd} {2}.",new Person3() { Name = "ZhezheToUpper" }.ToString(), DateTime.Now, DateTime.Now.DayOfWeek);
Console.WriteLine(msg13);
 

不同的结果的情况

上面的输出结果不同:


 这是不好的设计

 

 4.继续了解 IFormatProvider 和 ICustomFormatter 接口

到这里为止,应该说灵活应用string.Format()已经没什么多大的问题了,但是也还是存在一些问题,比如我们必须得为每个类单独去实现IFormattable接口才能实现自定义的格式化参数。在一些场后还是觉得不太方便或者说代码冗余。

.net的string.Format静态方法还提供了重载方法,具体签名如下:public static string Format(IFormatProvider provider,string format,params Object[] args)

 

这个方法比起原来使用的方法最前面增加了 IFormatProvider类型参数。使用此方法的优点是不需要为后面的参数对象实现 IFormattable  接口就可以使用自定义的格式化参数。既然这样的话也就解决了第4部分开头提到的问题了。

 

还是用例子说话吧

下面是正方形类

Square类
public class Square
    {
        public string Name { get; set; }

        /// <summary>
        /// 边长
        /// </summary>
        public double Side { get; set; }

        public override string ToString()
        {
            return string.Format("{0}(Side:{1})",Name, Side);
        }
    }
 

下面是长方形类


Rectangle类
 public class Rectangle
    {
        public string Name { get; set; }

        /// <summary>
        /// 宽
        /// </summary>
        public double Width { get; set; }

        /// <summary>
        /// 高
        /// </summary>
        public double Height { get; set; }


        public override string ToString()
        {
            return string.Format("{0}(Width:{1},Height:{2})",Name, Width, Height);
        }
    }
 

 两个类都重写了ToString方法

定义MyHelloFormatProvider类,该类从名称上就可以看出是格式化的提供者

 

 public class MyHelloFormatProvider : IFormatProvider
    {
        #region IFormatProvider Members

        public object GetFormat(Type formatType)
        {
            return new MyHelloFormatter();
        }

        #endregion
    }
 

该类实现了 IFormatProvider 接口,接口只有一个唯一的方法需要实现,GetFormat返回的是真正进行格式化操作的类,这里很像是工厂模式。

返回 MyHelloFormatter 对象之后,在MyHelloFormatter 中具体进行格式化操作。

 public class MyHelloFormatter : ICustomFormatter
    {
        #region ICustomFormatter Members

        public string Format(string format, object arg, IFormatProvider formatProvider)
        {
            var t = "Hello ";
            switch (format)
            {
                case "UPP":
                    t = t.ToUpper();
                    break;
                case "LOW":
                    t = t.ToLower();
                    break;
                default:
                   break;
            }

            return t + arg.ToString();
        }

        #endregion
    }
 

 

MyHelloFormatter 实现了ICustomFormatter接口,该接口也只有一个唯一的方法,即实际执行格式化的方法

如果不使用格式化参数或者格式化参数不匹配,情况会怎么样?

 

代码
var msg15 = string.Format(new MyHelloFormatProvider(), "{0}  {1}", new Rectangle() { Name = "MyRectangle", Width = 14.3, Height = 10 }, new Square() { Name = "MySquare", Side = 24.2 });
            Console.WriteLine(msg15);

            var msg16 = string.Format(new MyHelloFormatProvider(), "{0}  {1}", new Rectangle() { Name = "MyRectangle", Width = 14.3, Height = 10 }.ToString(), new Square() { Name = "MySquare", Side = 24.2 }.ToString());
            Console.WriteLine(msg16);

            var msg17 = string.Format(new MyHelloFormatProvider(), "{0:AAA}  {1:BBB}", new Rectangle() { Name = "MyRectangle", Width = 14.3, Height = 10 }, new Square() { Name = "MySquare", Side = 24.2 });
            Console.WriteLine(msg17);
 

以上输出都是一样的: Hello MyRectangle(Width:14.3,Height:10)  Hello MySquare(Side:24.2)

上面的运行结果表明,如果提供了new MyHelloFormatProvider() ,那么执行过程过是: 根据MyHelloFormatProvider 对象得到 MyHelloFormatter 对象,利用MyHelloFormatter 对象的Format方法进行格式化

这里还有一个问题,如果 MyHelloFormatProvider 的 GetFormat返回的不是一个实现了 ICustomFormatter 接口的对象又会是什么情况呢?

答案是会报异常。 那么如果返回的是 null 呢? 答案是直接调用了对象的ToString()方法了。如果返回null,则运行结果如下:

MyRectangle(Width:14.3,Height:10)  MySquare(Side:24.2)

 

带上格式化参数的运行结果

 

var msg18 = string.Format(new MyHelloFormatProvider(), "{0:UPP}  {1:LOW}", new Rectangle() { Name = "MyRectangle", Width = 14.3, Height = 10 }, new Square() { Name = "MySquare", Side = 24.2 });
            Console.WriteLine(msg18);
 

 HELLO MyRectangle(Width:14.3,Height:10)  hello MySquare(Side:24.2)


 通过上面的例子我们知道如果我们需要定义一种通用的格式化方式的话,不需要让类实现 IFormattable 接口,可以通过定义实现 IFormatProvider,ICustomFormatter接口的类去做,上面的无论是正方形还是长方形类都需要在前面加上 Hello 进行格式化,可以是普通的,小写的,大写的等等,不需要两个类单独去实现了,就选以后增加了圆形,三角形等等,也都能用我们已经定义好的 MyHelloFormatProvider 和 MyHelloFormatter  去进行格式化。

 

 

使用这种方式还能解决另外一个问题,假如我们已经为圆形类实现了 IFormattable  接口,并且已经实现了{0:UPP}格式化参数,但是实现的方法中没有加{0:LOW}格式化参数,而且这个类我们又不能更改(可能是.net自带的类,可能是第三方dll提供的类等等),那该怎么办呢? 显然已经不可能靠IFormattable  接口来解决了

使用这节讲的方法就可以实现我们要求了。以下是具体实现

圆形类
public class Circle : IFormattable
    {
        public string Name { get; set; }

        /// <summary>
        /// 半径
        /// </summary>
        public double Radius { get; set; }

        public override string ToString()
        {
            return string.Format("{0}(Radius:{1})", Name, Radius);
        }

        #region IFormattable Members

        public string ToString(string format, IFormatProvider formatProvider)
        {
            if (string.IsNullOrEmpty(format))
                return ToString();

            var t = "Hello ";
            switch (format)
            {
                case "UPP":
                    t = t.ToUpper();
                    break;
                default:
                    break;
            }

            return t + Name;
        }

        #endregion
    }
 

该类可以实现UPP格式化参数的格式化。

 var msg19 = string.Format("Test: {0}", new Circle() { Name = "MyCircle", Radius = 10 });
            Console.WriteLine(msg19);

            var msg20 = string.Format("Test: {0:UPP}", new Circle() {Name = "MyCircle", Radius = 10});
            Console.WriteLine(msg20);
 

运行上面的代码得到:

Test: MyCircle(Radius:10)
Test: HELLO MyCircle

第一个无格式化参数,实际调用ToString()方法得到,由代码 if (string.IsNullOrEmpty(format))决定

第二个带UPP格式化参数,也得到了预期的结果。

 

现在需要实现LOW的格式化参数

var msg21 = string.Format(new MyHelloFormatProvider(),"Test: {0:LOW}", new Circle() { Name = "MyCircle", Radius = 10 });
            Console.WriteLine(msg21);
 

在不修改Circle类并且不重新定义其他类的情况下就可以达到我们的要求了

显示结果如下: Test: hello MyCircle(Radius:10)      hello已经是全部小写了。

 

 

写了这么多,感觉有些乱七八糟了,发现还有很多没有提到,很多都讲重复了。本人也难得写博客,文字水平表达能力欠佳,还望阅者理解。

以下是全部代码
飞鸽传书:http://www.freeeim.com/ 彻底学通string.Format以及IFormattable,IFormatProvider,ICustomFormatter。

Android Input——输入系统介绍(一) Input 系统对于提供流畅、灵敏和一致的用户交互体验至关重要,它需要在不同的设备、场景和应用中保证输入事件的正确性、及时性和安全性。Android 输入系统是一个复杂但高效的设计,旨在处理来自各种输入设备(如触摸屏、键盘等)的用户交互,并将这些交互转换为应用程序可以理解和响应的形式。EventHub:输入系统的最底层,直接与硬件通信,监听和读取输入设备的原始事件。:从 EventHub 获取原始输入事件,对其进行解析,转化为更高层次的事件,以便上层应用或服务能够理解。 阅读详情

相关推荐

Win11家庭版如何让Win+R运行CMD默认管理员权限?3种方法实测有效

本文针对Win11家庭版用户,实测了三种让Win+R运行CMD默认获取管理员权限的有效方法。通过分析UAC机制与家庭版功能限制,详细介绍了注册表编辑、快捷方式创建与任务计划程序三种方案的原理、步骤与风险对比,帮助用户根据安全与效率需求选择最佳方案,实现一键高效管理。

sat99的博客 1277

FormattableString 取代特定区域字符串

有些软件系统是针对全球来开发的,因此一些字符串需要根据不同地区不同语言做出特定的处理。如果针对不同地区不同用语言分别编写字符串处理方法的话代码量是巨大的。那么这个时候我们可以用到内插字符串深层的特性,C# 会把内插字符串的结果隐式的转换成 string 或者 FormattableString 。 例如下面这个例子,内插字符串的结果将是 string 类型: string message = $"...

喵叔 3609

光谱预处理最简单实现方法--基于OpenSA光谱分析库

系列文章目录 “光晰本质,谱见不同”,光谱作为物质的指纹,被广泛应用于成分分析中。伴随微型光谱仪/光谱成像仪的发展与普及,基于光谱的分析技术将不只停留于工业和实验室,即将走入生活,实现万物感知,见微知著。本系列文章致力于光谱分析技术的科普和应用。 文章目录系列文章目录前言一、数据来源二、代码解读2.1 读取数据2 .2 划分数据集2 .3 返回训练集和测试集并绘制光谱图片2.4 建立1-D CNN模型2.5 训练1-D CNN模型2.6 测试1-D CNN模型2.7 运行CNN模型,并用查看结果总结

Echo_Code的博客 7069

字符串格式

格式字符串不限于内置类型,可以为自己的类型创建自定义格式字符串。为此,只需要实现接口IFormattable。 首先是一个简单的Person类,它包含FirstName和LastName属性。 class Person { public string FirstName{get;set;} public string LastName{get;set;} public Person(s...

singhwong 2704

大数据之VIP(Virtual IP,虚拟IP)负载均衡

VIP(Virtual IP,虚拟IP)负载均衡是一种在计算机网络中常用的技术,用于将网络请求流量均匀地分散到多个服务器上,以提高系统的可扩展性、可靠性和性能。

赵玉的专栏 4124

STM32F407 BootLoader实战:从零搭建到OTA升级(附完整源码)

本文详细介绍了为STM32F407微控制器从零搭建BootLoader并实现稳定OTA升级的完整实战指南。内容涵盖Flash分区规划、链接脚本配置、核心跳转逻辑、中断向量表重定向、可靠的升级流程设计,并深入探讨了双备份与回滚机制以提升工业级可靠性。文章提供了可直接使用的代码框架,并分享了关键调试技巧,帮助开发者快速掌握STM32远程固件更新技术。

weixin_29192211的博客 445

彻底学通string.Format以及IFormattable,IFormatProvider,ICustomFormatter

  自从使用.net以来就一直都在使用string.Format方法,一直没有空或者其他原因都没有深入去了解,主要还是因为项目上似乎没有这么高的要求,也没必要去深入了解,就算碰到了自定义的格式化内容也是写几个通用的方法而已。今天空下来仔细去理解了一下,在这里和大家分享一下,也希望大家一起交流。 string.Format方法是string类提供的静态方法,一般最多使用的是其两个参...

anzdnbs11538的博客 237

中移物联ML307C模组OPENCPU开发环境搭建全攻略

本文详细介绍了中移物联ML307C模组OPENCPU开发环境搭建的全过程。从OPENCPU模式的核心优势解析,到SDK获取、Python与scons工具安装,再到解读SDK目录结构与实战编译命令,最后提供常见问题避坑指南,帮助开发者快速构建高效的物联网应用编译环境。

weixin_29168393的博客 746

同事都说有SQL注入风险,我非说没有

细节很重要~~~

zyq025的专栏 7696

医学图像分割实战:基于TransUNet训练自己的眼底硬渗出物数据集(附完整代码)

本文详细介绍了基于TransUNet的眼底硬渗出物分割实战指南,涵盖数据预处理、模型调优、训练策略及性能优化等关键环节。通过代码复现和实验对比,展示了TransUNet在医学图像分割中的优势,为糖尿病视网膜病变的早期诊断提供技术支持。

weixin_42524708的博客 364

软件测试面试题之易错题

(1)白盒测试:又称功能功能 测试、数据驱动测试和行为测试,是一种从用户观点出发的测试,被测程序为黑盒子, 通过测试来检测每个功能是否能够正常使用。(2)黑盒测试:又称结构测试和逻辑驱动 测试,是知道产品内部工作过程,通过测试来检测产品内部动作是否按照规格说明书 的规定去正常运行。(1)、测试需求分析;(2)动态白盒测试:需要对各个模块功能、模块间的接口、局部数据结构、主要执行路径、 错误处理等方面的测试。(2) 集成测试所测试的对象是模块间的接口,其目的是在找出在模块接口上面,包括整体体系结构上的问题;

m0_37449634的博客 681

AI对齐通讯第200期核心议题解析

AI对齐(AI Alignment)是确保人工智能系统目标与人类价值观一致的基础性研究方向,其核心原理涵盖价值学习、可解释性监督与稳健偏好建模。随着大语言模型能力边界持续扩展,对齐技术正从理论探索转向工程化落地,显著提升模型在安全关键场景(如医疗辅助决策、金融合规响应、教育内容生成)中的可信度与可控性。《The AI Alignment Newsletter》作为该领域最具影响力的周期性综述载体,持续聚合全球前沿进展,其中第200期重点聚焦于可验证对齐评估框架与基于人类反馈的迭代优化实践,为从业者提供兼具学

weixin_34414650的博客 1040

Python实现商品价格监控与波动分析爬虫项目

本文通过完整的代码示例和详细的技术讲解,展示了如何实现商品价格的自动监控和波动分析。该项目不仅适用于个人购物助手,还可以扩展为商家的竞品监控工具。通过结合数据抓取、存储、分析与可视化,能够帮助我们更好地理解市场趋势并做出优化决策。

2201_76125261的博客 1743

C#中的字符串格式操作

C#中的字符串格式操作 一、C#中的字符串内插:$   'KaTeX parse error: Expected 'EOF', got '&' at position 83: …果的字符串表示形式。 &̲ensp;&ensp;声明内插…“内插字符串”;内插字符串包含使用{}来插入表达式。   格式:{内插表达式,最小字符数:字符串格式} string nam...

六斤的小猪猪呀 1150

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

[格式化输出] 关于IFormattable, IFormatProvider 和 ICustomFormatter的概念和使用

曾经一度为格式化输出而困惑,看着满天遍野的结构,都不敢去轻易触动。只能使用最安全,但是 低能的object.ToString()方法。终于忍受不了这种窘困的处境,下力气研究一番,也算是有点心得,希望和大家交流一下。鉴于该格式化输出的结构过于繁琐,我不希望文章陷入条款的解释,于是,我从一个实际问题入手,一步一步地介绍格式化输出的概念,三个接口的意义,以及使用接口的一种模式(Pattern)。

fancymsman的专栏 1687

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

C# 自定义格式字符串

引言String可能是使用最多的类型,ToString()则应该是大家使用得最多的方法了。然而它不应该仅仅是用来输出类型的名称,如果使用得当,它可以方便地输出我们对类型自定义的格式。本文将循序渐进地讨论ToString(),以及相关的IFormattable、IFormatProvider以及ICustomFormatter接口。在类型内部提供自定义格式字符串的能力继承自Syste

zyyjc的专栏 4445

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

.net(C#)中String.Format如何使用

说明: String.Format 将指定的 String 中的每个格式项替换为相应对象的值的文本等效项。 例子: int iVisit = 100; string szName = "Jackfled"; Response.Write(String.Format("您的帐号是:{0} 。访问了 {1} 次.", szName, iVisit)); C#的String.Format举例20

路雪军 Carl 2192

net中的string.format

DataGrid-数据格式设置表达式数据格式设置表达式.NET Framework 格式设置表达式,它在数据显示在列中之前先应用于数据。此表达式由可选静态文本和用以下格式表示的格式说明符组成:{0:format specifier} 0 是参数索引,它指示列中要格式化的数据元素;因此,通常用零来指示第一个(且唯一的)元素。format specifier 前面有一个冒号 (:),它由一个或多个字...

changyehappy的专栏 491

.net string,format函数

格式化数值结果表字符说明示例输出C 货币 string.Format("{0:C3}", 2) $2.000 D 十进制 string.Format("{0:D3}", 2) 002 E 科学计数法 1.20E+001 1.20E+001 G 常规 string.Format("{0:G}", 2) 2 N 用分号隔开的数字 string.Format("{0:N}"...

weixin_34232363的博客 298

C#面:如何使用 IFormattable 接口实现格式化输出

需要注意的是,实现 IFormattable 接口并不会自动应用于所有的 ToString 方法调用。需要显式地调用对象的 ToString 方法,并传入格式字符串和格式化提供程序。在方法中,可以根据提供的格式字符串和格式化提供程序 (ToStringformatProvider) 来决定如何格式化输出。可以使用标准的格式字符串,也可以自定义格式字符串。在上面的示例中,我们使用了标准的格式字符串"F",并传入了当前的区域设置作为格式化提供程序。

那个那个鱼的博客 508

[性能优化] C# Formatted String 特性

C#中的FormattableString将字符串创建与格式化操作分离,在不需要立即输出时能避免性能开销。性能测试显示,当不需要真实输出时,使用FormattableString比直接格式化快5倍;而当需要输出时,两者性能相当。但要注意,对于无参数的字符串,强制使用FormattableString会带来10倍性能恶化。此外,应避免string与FormattableString的函数重载,因编译器会优先选择string版本,可能导致意外行为。合理使用FormattableString可优化字符串处理性能。

三叔的博客 671

.Net string.Format格式参考[转载]

字符串的数字格式 stringstr1 =string.Format("{0:N1}",56789); //result: 56,789.0 stringstr2 =string.Format("{0:N2}",56789); //result: 56,789.00 stringstr3 =string.Format("{0:N3}",56789); //result...

weixin_30410999的博客 242

String.format() 用法

有了Slf4j的MessageFormatter类,我个人目前已经对String.format放弃了。当然,有些小伙伴已经习惯了String.format的使用,那就接着用。技术方案没有最好的,只有最适合自己的!加班写代码已经够苦了,平时还不怎么爽怎么来!

huang714的专栏 639

C#中接口IFormattable/IFormatProvider/ICustomFormatter的区别与用法

定义 1.接口IFormattable:如果需要将自己的格式化包含在某个类上,在该类上实现IFormattable接口中的ToString。例如int32继承了此接口: public struct Int32 : ... , IFormattable, ...{...} 2、接口ICustomFormatter:如果希望自定义格式化并使它可供多个不同类使用,那么实现ICustomFormatter接口的Format函数。例如:自定义格式化MyBaseFormat,继承接口ICustomFormatter和

angelsha417的博客 1528

IFormattable笔记

参考:http://kb.cnblogs.com/page/69729/1/ 先看一个例子 不知道是否有印象 有时候我们从数据库中读出时间后,想输出1988-10-10这样格式的时间时,一般要把string先Convert.ToDateTime然后再.ToString("yyyy-MM-dd"); 但是string型的 字符串直接点ToString()是没有这样的功能的 这说明了Date...

weixin_34066347的博客 172

string.Format 格式化时间,货币

1、格式化货币(跟系统的环境有关,中文系统默认格式化人民币,英文系统格式化美元) string.Format("{0:C}",0.2) 结果为:¥0.20 (英文操作系统结果:$0.20) 默认格式化小数点后面保留两位小数,如果需要保留一位或者更多,可以指定位数string.Format("{0:C1}",23.15) 结果为:¥23.2 (截取会自动四舍五入) 格式化多个Object实例s...

weixin_30647065的博客 365
上一篇: 『飞鸽』百度悄然进军客户端领域
下一篇: 『飞秋』Html.Label的缺陷及补救办法
普通网友
博客等级 码龄22年 1万+粉丝 3156原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值