字符串介绍篇

一、创建字符串

      1、string是一个不可变的数据类型,一旦对字符串对象进行了初始化,该字符串对象就不能改变了。修改字符串内容的方法和运算符实际上是创建一个新的字符串。

            例如:string text = "This is a introduction。";text += "This is a Text";从语法上看,后一行代码是把更多的文本添加到字符串中。实际上并非如此,而是创建一个新字符串实例,给它分配足够的内存,以保存合并起来的文本。最初的文本"This is a introduction。"复制到这个新字符串中,再加上额外的文本"This is a Text"。然后更新存储在变量text中的地址,使变量正确地指向新的字符串对象。旧的字符串对象被撤消了引用----不再有变量引用它,下一次垃圾收集器清理应用程序中所有未使用的对象时,就会删除它。所以需要对字符串变量进行多次操作时将使用下面介绍的内容。

      2、StringBuilder

            在使用String类构造一个字符串时,要给它分配足够的内存来保存字符串,但StringBuilder通常分配的内存会比需要的更多。开发人员可以选择显示指定,但如果没有显示指定,存储单元量在默认情况下就根据StringBuilder初始化时的字符串长度来确定。它有两个主要的属性:

                  2.1、Length 指定字符串的实际长度;

                  2.2、Capacity 是字符串占据存储单元的长度。

            对字符串的修改就在赋予StringBuilder实例的存储单元中进行,这就大大提高了添加子字符串和替换单个字符的效率。删除或插入子字符串仍然效率低下,因为这需要移动随后的字符串。只有执行扩展字符串容量的操作,才会给字符串分配需要的新内存,才可能移动包含的整个字符串。在添加额外的容量时,从经验来看,StringBuilder如果检测到容量超出,且该容量中没有显示设置新值,就会使自己的容量翻倍。

            例如:StringBuilder text = new  StringBuilder("This is a introduction。", 100);text.Append("This is a Text");

      一般,使用StringBuilder可以执行字符串的任何操作,String可以用于存储字符串或显示最终结果。

 二、格式化字符串

       格式字符串本身大都由要显示的文本组成,但只要有要格式化的变量,它在参数列表中的下标就必须放在括号中。在括号中还可以有与该项的格式相关的其他信息,例如可以包含:

      1、该项的字符串表示要占用的字符数,这个信息的前面应有一个逗号,负值表示该项应左对齐,正值表示该项应右对齐。如果该项占用的字符数比给定的多,其内容也会完整地显示出来。

      2、格式说明符也可以显示出来。它的前面应有一个冒号,表示应如何格式化该项。

      例如:double d = 45;int i = 10;Console.WriteLine("The double is {0,10:E}.", d);

      字符串的格式化

      就上面的double d = 45;int i = 10;Console.WriteLine("The double is {0,10:E}.", d);示例,实际上过程是

[HostProtection(SecurityAction.LinkDemand, UI = true)]

public static void WriteLine(string format, object arg0)

{

    Out.WriteLine(format, arg0);

}

跳转到下面的函数中

public virtual void WriteLine(string format, object arg0)

{

    this.WriteLine(string.Format(this.FormatProvider, format, new object[] { arg0 }));

}

 (stringvalue){//代码省略,只是显示string.Format返回的字符串},而string.Format的定义为

public static string Format(IFormatProvider provider, string format, params object[] args)

{

    if ((format == null) || (args == null))

    {

        throw new ArgumentNullException((format == null) ? "format" : "args");

    }

    StringBuilder builder = new StringBuilder(format.Length + (args.Length * 8));

    builder.AppendFormat(provider, format, args);

    return builder.ToString();

}

即最终跳转到StringBuilder的AppendFormat方法。【由于AppendFormat的内容比较多,这里不加显示,想了解具体方法体,可反编译System.dll查看】StringBuilder.AppendFormat()需要指出如何格式化对象,它首先检查对象,确认它是否执行System命名空间中的接口IFormattable。只要试着把这个对象转换为接口,看看转换是否成功即可。如果测试失败,AppendFormat()只会调用对象的ToString()方法,所有的对象都从System.Object继承了这个方法或重写了该方法。

      但是,所有预定义的基本数字类型都执行这个接口,对于这些类型,特别是这个示例中的double,就不会调用继承自System.Object的基本ToString()方法。为了理解这个过程,需要了解IFormattable接口。

      IFormattable只定义了一个方法,该方法也叫作ToString(),它带有两个参数,这与System.Object版本的ToString()不同,它不带参数。下面是IFormattable的定义:

[ComVisible(true)]

public interface IFormattable

{

    // Methods

    string ToString(string format, IFormatProvider formatProvider);

}

这个ToString()重载方法的第一个参数是一个字符串,它指定要求的格式。换言之,它是字符串的说明符部分,放在字符串的{}中。例如上面的示例double d = 45;int i = 10;Console.WriteLine("The double is {0,10:E}.", d);中,在double变量d上调用这个重载方式,传递给它的第一个参数是E,即格式说明符内冒号后面的文本。第二个参数暂时不介绍,但如果formatProvider为空,ToString()就要使用系统设置中指定的文化背景信息。下一个要格式化的对象是int,它不需要任何特殊的格式。由于没有格式要求,StringBuilder.AppendFormat()会给该格式字符串传递一个空引用,并适当地响应带有两个参数的ToString()重载方法。

      示例

  1. using System;

  2. using System.Text;

  3.  

  4. namespace Text

  5. {

  6.     class MainEntryPoint

  7.     {

  8.         static void Main()

  9.         {

  10.             Vector v1 = new Vector(1, 32, 5);

  11.             Vector v2 = new Vector(845.4, 54.3, -7.8);

  12.             Console.WriteLine("\nIn IJK format,\nv1 is {0,30:IJK}\nv2 is {1,30:IJK}", v1, v2);

  13.             Console.WriteLine("\nIn default format,\nv1 is {0,30}\nv2 is {1,30}", v1, v2);

  14.             Console.WriteLine("\nIn VE format\nv1 is {0,30:VE}\nv2 is {1,30:VE}", v1, v2);

  15.             Console.WriteLine("\nNorms are:\nv1 is {0,20:N}\nv2 is {1,20:N}", v1, v2);

  16.             Console.ReadLine();

  17.         }

  18.     }

  19.  

  20.     struct Vector : IFormattable

  21.     {

  22.         public double x, y, z;

  23.  

  24.         public Vector(double x, double y, double z)

  25.         {

  26.             this.x = x;

  27.             this.y = y;

  28.             this.z = z;

  29.         }

  30.  

  31.         public string ToString(string format, IFormatProvider formatProvider)

  32.         {

  33.             if (format == null) return ToString();

  34.             string formatUpper = format.ToUpper();

  35.             switch (formatUpper)

  36.             {

  37.                 case "N":

  38.                     return "|| " + Norm().ToString() + " ||";

  39.                 case "VE":

  40.                     return String.Format("( {0:E}, {1:E}, {2:E} )", x, y, z);

  41.                 case "IJK":

  42.                     StringBuilder sb = new StringBuilder(x.ToString(), 30);

  43.                     sb.Append(" i + ");

  44.                     sb.Append(y.ToString());

  45.                     sb.Append(" j + ");

  46.                     sb.Append(z.ToString());

  47.                     sb.Append(" k");

  48.                     return sb.ToString();

  49.                 default:

  50.                     return ToString();

  51.             }

  52.         }

  53.  

  54.         public Vector(Vector rhs)

  55.         {

  56.             x = rhs.x;

  57.             y = rhs.y;

  58.             z = rhs.z;

  59.         }

  60.  

  61.         public override string ToString()

  62.         {

  63.             return "( " + x + " , " + y + " , " + z + " )";

  64.         }

  65.  

  66.         public double this[uint i]

  67.         {

  68.             get

  69.             {

  70.                 switch (i)

  71.                 {

  72.                     case 0:

  73.                         return x;

  74.                     case 1:

  75.                         return y;

  76.                     case 2:

  77.                         return z;

  78.                     default:

  79.                         throw new IndexOutOfRangeException(

  80.                            "Attempt to retrieve Vector element" + i);

  81.                 }

  82.             }

  83.             set

  84.             {

  85.                 switch (i)

  86.                 {

  87.                     case 0:

  88.                         x = value;

  89.                         break;

  90.                     case 1:

  91.                         y = value;

  92.                         break;

  93.                     case 2:

  94.                         z = value;

  95.                         break;

  96.                     default:

  97.                         throw new IndexOutOfRangeException(

  98.                            "Attempt to set Vector element" + i);

  99.                 }

  100.             }

  101.         }

  102.  

  103.         private const double Epsilon = 0.0000001;

  104.  

  105.         public static bool operator ==(Vector lhs, Vector rhs)

  106.         {

  107.             if (Math.Abs(lhs.x - rhs.x) < Epsilon && Math.Abs(lhs.y - rhs.y) < Epsilon &&

  108.                 Math.Abs(lhs.z - rhs.z) < Epsilon)

  109.                 return true;

  110.  

  111.             return false;

  112.         }

  113.  

  114.         public static bool operator !=(Vector lhs, Vector rhs)

  115.         {

  116.             return !(lhs == rhs);

  117.         }

  118.  

  119.         public static Vector operator +(Vector lhs, Vector rhs)

  120.         {

  121.             Vector Result = new Vector(lhs);

  122.             Result.x += rhs.x;

  123.             Result.y += rhs.y;

  124.             Result.z += rhs.z;

  125.             return Result;

  126.         }

  127.  

  128.         public static Vector operator *(double lhs, Vector rhs)

  129.         {

  130.             return new Vector(lhs * rhs.x, lhs * rhs.y, lhs * rhs.z);

  131.         }

  132.  

  133.         public static Vector operator *(Vector lhs, double rhs)

  134.         {

  135.             return rhs * lhs;

  136.         }

  137.  

  138.         public static double operator *(Vector lhs, Vector rhs)

  139.         {

  140.             return lhs.x * rhs.x + lhs.y + rhs.y + lhs.z * rhs.z;

  141.         }

  142.  

  143.         public double Norm()

  144.         {

  145.             return x * x + y * y + z * z;

  146.         }

  147.     }

  148. }

 

转载于:https://www.cnblogs.com/swollaws/archive/2009/07/08/1519231.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值