int)、int.Parse、int.tryParse、Convert.ToInt32的区别?
Convert.ToInt32 与 int.Parse 较为类似,实际上 Convert.ToInt32 内部调用了 int.Parse:
Convert.ToInt32 参数为 null 时,返回 0; int.Parse 参数为 null 时,抛出异常。
Convert.ToInt32 参数为 "" 时,抛出异常; int.Parse 参数为 "" 时,抛出异常。
Convert.ToInt32 可以转换的类型较多; int.Parse 只能转换数字类型的字符串。
int.TryParse 与 int.Parse 又较为类似,但它不会产生异常,转换成功返回 true,转换失败返回 false。最后一个参数为输出值,如果转换失败,输出值为 0。
(int) 属 cast 转换,只能将其它数字类型转换成 int 类型,它不能转换字符串,比如下例就会失败:
string v = "1"; int n = (int)v;
ToString()、Convert.ToString()、(string)、as string 的区别
通常object到 string有四种方式(假设有object obj):obj.ToString()、Convert.ToString()、(string)obj、obj as string。他们都能将 object 对象转换成 string 对象。我就讲讲他们的异同以及在实际中应该使用哪个。
前两个方法通常是由别的对象得到 string 对象,它们间的区别只表现在要转换的对象为 null 时,如果 obj 为 null,调用 obj.ToString 方法会导致 NullReferenceException 异常,调用 Convert.ToString 不会抛出异常而返回一个 null。
用强制转换 (string)obj 要求 obj 的运行时类型必须是 string。如果不是,就会抛出异常。用 as 方法则会相对平稳,当 obj 的运行时类型不是 string 时会返回 null 而不抛出异常。
所以在通常在我们需要得到某个对象的 string 表达形式时,我们应该使用 ToString 和 Convert.ToString,这时候你就得根据情形选一个,假如你能保证你的对象不为 null,则两个差不多。如果有可能为 null,你就应该用 Convert.ToString,如果你希望它为 null 的时候抛出异常,那么当然可以选择 ToString。
C# 中String和 Stringbuilder的区别
String 对象是不可改变的。每次使用 String 类中的方法之一或进行运算时(如赋值、拼接等)时,都要在内存中创建一个新的字符串对象,这就需要为该新对象分配新的空间。而 StringBuilder 则不会,在需要对字符串执行重复修改的情况下,创建新的 String 对象相关的系统开销可能会非常昂贵。如果要修改字符串而不创建新的对象,则可以使用 System.Text.StringBuilder 类;例如,当在一个循环中将许多字符串连接在一起时,使用 StringBuilder 类可以提升性能。
1、设置容量与长度
StringBuilder MyStringBuilder = new StringBuilder("Hello World!", 25); 方式1
MyStringBuilder.Capacity = 25; 方式2
EnsureCapacity 方法可用来检查当前 StringBuilder 的容量。如果容量大于传递的值,则不进行任何更改;但是,如果容量小于传递的值,则会更改当前的容量以使其与传递的值匹配。
也可以查看或设置 Length 属性。如果将 Length 属性设置为大于 Capacity 属性的值,则自动将 Capacity 属性更改为与 Length 属性相同的值。如果将 Length 属性设置为小于当前 StringBuilder 对象内的字符串长度的值,则会缩短该字符串。
2、 修改 StringBuilder 字符串
方法名 使用
StringBuilder.Append 将信息追加到当前 StringBuilder 的结尾
StringBuilder.AppendFormat 用带格式文本替换字符串中传递的格式说明符
StringBuilder.Insert 将字符串或对象插入到当前 StringBuilder 对象的指定索引处
StringBuilder.Remove 从当前 StringBuilder 对象中移除指定数量的字符
StringBuilder.Replace 替换指定索引处的指定字符
Append 方法可用来将文本或对象的字符串表示形式添加到由当前 StringBuilder 对象表示的字符串的结尾处。下面的示例将一个 StringBuilder 对象初始化为“Hello World”,然后将一些文本追加到该对象的结尾处。将根据需要自动分配空间。
StringBuilder MyStringBuilder = new StringBuilder("Hello World!");
MyStringBuilder.Append(" What a beautiful day.");
Console.WriteLine(MyStringBuilder);
//此示例将 Hello World! What a beautiful day. 显示到控制台。
AppendFormat 方法将文本添加到 StringBuilder 的末尾,而且实现了 IFormattable 接口,因此可接受格式化部分中描述的标准格式字符串。可以使用此方法来自定义变量的格式并将这些值追加到 StringBuilder 的后面。下面的示例使用 AppendFormat 方法,将一个设置为货币值格式的整数值放到 StringBuilder 的末尾。
int MyInt = 25;
StringBuilder MyStringBuilder = new StringBuilder("Your total is ");
MyStringBuilder.AppendFormat("{0:C} ", MyInt);
Console.WriteLine(MyStringBuilder);
//此示例将 Your total is $25.00 显示到控制台。
Insert 方法将字符串或对象添加到当前 StringBuilder 中的指定位置。下面的示例使用此方法将一个单词插入到 StringBuilder 的第六个位置。
StringBuilder MyStringBuilder = new StringBuilder("Hello World!");
MyStringBuilder.Insert(6, "Beautiful ");
Console.WriteLine(MyStringBuilder);
//此示例将 Hello Beautiful World! 显示到控制台。
Remove 方法从当前 StringBuilder 中移除指定数量的字符,移除过程从指定的从零开始的索引处开始。下面的示例使用 Remove 方法缩短 StringBuilder。
StringBuilder MyStringBuilder = new StringBuilder("Hello World!");
MyStringBuilder.Remove(5, 7);
Console.WriteLine(MyStringBuilder);
//此示例将 Hello 显示到控制台。
使用 Replace 方法,可以用另一个指定的字符来替换 StringBuilder 对象内的字符。下面的示例使用 Replace 方法来搜索 StringBuilder 对象,查找所有的感叹号字符 (!),并用问号字符 (?) 来替换它们。
StringBuilder MyStringBuilder = new StringBuilder("Hello World!");
MyStringBuilder.Replace('!', '?');
Console.WriteLine(MyStringBuilder);
//此示例将 Hello World? 显示到控制台。
3、将Stringbuilder串转换为string形式
string = StringBuilder.toString();
C#中字符串的内存分配与驻留池
刚开始学习C#的时候,就听说CLR对于String类有一种特别的内存管理机制:有时候,明明声明了两个String类的对象,但是他们偏偏却指向同一个实例。如下:
String s1 = "Hello";
String s2 = "Hello";
//s2和s1的实际值都是Hello
bool same = (object) s1 == (object) s2;
//这里比较s1、s2是否引用了同一个对象实例
//所以不能写作bool same = s1 == s2;
//因为String类重载了==操作符来比较String对象包含的实际值
这里的same会被赋值为true。也就是说s1真的和s2引用了同一个String对象。当然,应该注意到的是s1和s2都被统一赋值为同一个字符串Hello,这才是出现上述情况的原因。
现在我们初步得出结论,当有多个字符串变量包含了同样的字符串实际值时,CLR可能不会为它们重复地分配内存,而是让它们统统指向同一个字符串对象实例。(这里我说了可能,是因为某些情况下,确实也会发生同一个字符串实际值在内存中有多份副本同时存在。请继续往下看。)
我们知道,String类有很多特别的地方,其中之一就是它是不会改变的(immutable)。这说明在我们每次对一个String对象进行操作时(比如说使用Trim,Replace等方法),并不是真的对这个String对象的实例进行修改,而是返回一个新的String对象实例作为操作执行的结果。String对象的实例一经生成,到死都不会被改变了!
基于String类这样的特性,CLR让表示相同的字符串实际值的变量指向同一个String事例,就是完全合理的了。因为利用任何一个对String实例的引用所进行的修改操作都不会切实地影响到该实例的状态,也就不会影响到其他所有指向该实例的引用所表示的字符串实际值。CLR如此管理String类的内存分配,可以优化内存的使用情况,避免内存中包含冗余的数据。
为了实现这个机制,CLR默默地维护了一个叫做驻留池(Intern Pool)的表。这个表记录了所有在代码中使用字面量声明的字符串实例的引用。这说明使用字面量声明的字符串会进入驻留池,而其他方式声明的字符串并不会进入,也就不会自动享受到CLR防止字符串冗余的机制的好处了。这就是我上文提到的某些情况下,确实也会发生同一个字符串实际值在内存中有多份副本同时存在的例子。请看这个例子:
StringBuilder sb = new StringBuilder();
sb.Append("He").Append("llo");
string s1 = "Hello";
string s2 = sb.ToString();
bool same = (object) s1 == (object) s2;
这时same就不是true了,因为虽然s1,s2表示的是相同的字符串,但是由于s2不是通过字面量声明的,CLR在为sb.ToString()方法的返回值分配内存时,并不会到驻留池中去检查是否有值为Hello的字符串已经存在了,所以自然不会让s2指向驻留池内的对象。
为了让编程者能够强制CLR检查驻留池,以避免冗余的字符串副本,String类的设计者提供了一个名为Intern的类方法。下面是该方法的一个示例:
StringBuilder sb = new StringBuilder();
sb.Append("He").Append("llo");
string s1 = "Hello";
string s2 = String.Intern(sb.ToString());
bool same = (object) s1 == (object) s2;
好了,same又是true了。Intern方法接受一个字符串作为参数,它会在驻留池中检查是否存在参数所表示的字符串。如果存在,则返回那个驻留池中的字符串的引用;否则向驻留池中加入一个新的表示相同值的字符串,并返回这个字符串的引用。不过要注意的是,就算Intern方法在驻留池中找到了相同值的字符串,也不能让您省却一次字符串内存分配的操作,因为作为参数的字符串已经被分配了一次内存了。而使用Intern方法的好处在于,如果Intern方法在驻留池中找到了相同值的字符串,此时虽然在内存中存在两份该字符串的副本(一份是参数,一份是驻留池中的),但是随着时间的流逝,参数所引用的那个副本会被垃圾回收掉,这样对于该字符串内存中就不存在冗余了。
当您的程序中存在某个方法,可以根据不同的上下文环境创建并返回一个很长的字符串,而在程序运行的过程中它有会经常返回同样的字符串时,您可能就要考虑考虑使用Intern方法来提高内存的利用率了。不过同样值得注意的是,使用Intern方法让一个字符串存活于驻留池中也有一个副作用:即使已经不存在任何其它引用指向驻留池中的字符串了,这个字符串仍然不一定会被垃圾回收掉。也就是说即使驻留池中的字符串已经没有用处了,它可能也要等到CLR终结时才被销毁。当您使用Intern方法的时候,也应该考虑到这个特殊的行为。
字符串格式化汇总:
C
货币
2.5.ToString("C")
¥2.50
D
十进制数
25.ToString("D5")
00025
E
科学型
25000.ToString("E")
2.500000E+005
F
固定点
25.ToString("F2")
25.00
G
常规
2.5.ToString("G")
2.5
N
数字
2500000.ToString("N")
2,500,000.00
X
十六进制
255.ToString("X")
FF
formatCode 是可选的格式化代码字符串。
必须用“{”和“}”将格式与其他字符分开。如果恰好在格式中也要使用大括号,可以用连续的两个大括号表示一个大括号,即: “{{”或者“}}”。
常用格式举例:
(1) int i=12345;
this.textBox1.Text=i.ToString();
//结果 12345(this指当前对象,或叫当前类的实例)
this.textBox2.Text=i.ToString("d8"); //结果 00012345
(2) int i=123;
double j=123.45;
string s1=string.Format("the value is {0,7:d}",i);
string s2=string.Format("the value is {0,7:f3}",j);
this.textBox1.Text=s1 ; //结果 the value is 123
this.textBox2.Text=s2; //结果 the value is 123.450
(3)double i=12345.6789;
this.textBox1.Text=i.ToString("f2"); //结果 12345.68
this.textBox2.Text=i.ToString("f6");//结果 12345.678900
(4)double i=12345.6789;
this.textBox1.Text=i.ToString("n"); //结果 12,345.68
this.textBox2.Text=i.ToString(“n4”); //结果 12,345.6789
(5)double i=0.126;
string s=string.Format("the value is {0:p}",i);
this.textBox1.Text=i.ToString("p"); //结果 12.6%
this.textBox2.Text=s; //结果 the value is 12.6%
(6) DateTime dt =new DateTime(2003,5,25);
this.textBox1.Text=dt.ToString("yy.M.d"); //结果 03.5.25
this.textBox2.Text=dt.ToString(“yyyy年M月”);//结果 2003年5月
Convert.ToDateTime("2005/12/22 22:22:22").ToString("yyyy/MM/dd HH:mm:ss")
"2005/12/22 22:22:22"
(7) int i=123;double j=123.45;
string s=string.Format("i:{0,-7},j:{1,7}",i,j); //-7表示左对齐,占7位
this.textBox1.Text=s ; //结果i:123 ,j: 123.45
(8) string s7 = String.Format("{0:(###) ###-####}", 8005551212)
//生成(800) 555-1212
int a = 12345678;double b = 1234.12543;
string s8= String.Format("abcd{0:C}abcd", b);//abcd¥1,234.13abcd
string s9 = "abcd" + b.ToString("C") + "abcd";//abcd¥1,234.13abcd
string s10 = String.Format("{0:C3}", b);//¥1,234.125
string s11 = b.ToString("C3");//¥1,234.125
string s12 = String.Format("{0:d}", a);//十进制--12345678
string s14 = String.Format("{0:e}", a);//指数--1.234568e+007
string s16 = String.Format("{0:f}", a);//定点数--12345678.00
string s18 = String.Format("{0:n}", a);//数值--12,345,678.00
string s20 = String.Format("{0:x}", a);//十六进制--bc614e
string s22 = String.Format("{0:g}", a);//通用为最紧凑—12345678
b = 4321.12543;a = 1234;
string s24 = String.Format("{0:000000}", a);// 001234
string s25 = String.Format("{0:000000}", b);// 004321
//# 描述:占位符,如果可能,填充位
string s26 = String.Format("{0:#######}", a);// 1234
string s27 = String.Format("{0:#######}", b);// 4321
string s28 = String.Format("{0:#0####}", a);// 01234
string s29 = String.Format("{0:0#0000}", b);// 004321
//. 描述:小数点
string s30 = String.Format("{0:000.000}", a);//1234.000
string s31 = String.Format("{0:000.000}", b);//4321.125
b = 87654321.12543;a = 12345678;
//, 描述:数字分组,也用于增倍器
string s32 = String.Format("{0:0,00}", a);// 12,345,678
string s33 = String.Format("{0:0,00}", b);// 87,654,321
string s34 = String.Format("{0:0,}", a);// 12346
string s35 = String.Format("{0:0,}", b);// 87654
string s36 = String.Format("{0:0,,}", a);// 12
string s37 = String.Format("{0:0,,}", b);// 88
string s38 = String.Format("{0:0,,,}", a);// 0
string s39 = String.Format("{0:0,,,}", b);// 0
// % 描述:格式为百分数
string s40 = String.Format("{0:0%}", a);// 1234567800%
string s41 = String.Format("{0:#%}", b);// 8765432113%
string s42 = String.Format("{0:0.00%}", a);// 1234567800.00%
string s43 = String.Format("{0:#.00%}", b);// 8765432112.54%
如何进行字节数组和字符串的相互转换?
将字符串转换为字节数组时,需要调用System.Text.Encoding命名空间中各种编码类的GetBytes方法,而将字节数组转换为字符串时,则需要调用System.Text.Encoding命名空间中的各种编码的GetString方法。例如:
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string s = "nbjjjlljjoijio";
byte[] bytes = Encoding.Default.GetBytes(s);
string ss = string.Empty;
for (int i = 0; i < bytes.Length; i++)
{
ss += bytes[i].ToString();
}
Console.WriteLine(ss);
ss = Encoding.Default.GetString(bytes);
Console.WriteLine(ss);
}
}
}
把一个整数分解成2的次幂
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1() {InitializeComponent();}
private List<int> tempList = new List<int>();
private void button1_Click(object sender, EventArgs e)
{
tempList.Clear(); listBox1.Items.Clear();
int intValue = Convert.ToInt32(textBox1.Text.Trim());
GetList(intValue);
foreach (int i in tempList)
listBox1.Items.Add(i);
}
private void GetList(int value)
{
if (value == 0)
return;
for (int i = value; i > 0; i--)
{
if ((i & (i - 1)) == 0)//如果是2的次
{//幂则与本身的下位相与为0
tempList.Add(i);
GetList(value - i);
break;
}
}
}
}
}
将字符串 1234||1123||2344||123||567按||分成数组:
String ss=” 1234||1123||2344||123||567”;
string[] mobileArray=ss.Replace(“||”,”,”).Split(‘,’);
字母和ASCII的转换。
namespace WindowsFormsApplication2
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void btnToASC_Click(object sender, EventArgs e)
{
if (txtChar.Text != string.Empty)
{
if (Encoding.GetEncoding("unicode").GetBytes(new char[] {txtChar.Text[0]})[1] == 0)
{
txtToASC.Text = Encoding.GetEncoding("unicode").GetBytes(txtChar.Text)[0].ToString();
//得到ASCII值
}
else
{
txtToASC.Text = ""; MessageBox.Show("请输入字母","提示");
}
}
}
private void btnToChar_Click(object sender, EventArgs e)
{
if (txtASC.Text != string.Empty)
{
int intNum;
if (int.TryParse(txtASC.Text, out intNum))
{//将ASCII转换为字符。
txtToChar.Text =((char)intNum).ToString();
}
}
}
}
汉字和区位码之间的转换。
过程:通过Encoding对象的GetBytes方法得到汉字的字节数组,将字节数的第一位和第二位分别转为整形数值,然后将得到的两个整形数值分别减160后转换为字符串,连接两个字符串就组成了汉字区位码。
namespace ChineseCode
{
public partial class Frm_Main : Form
{
public Frm_Main()
{
InitializeComponent();
}
private void btn_Get_Click(object sender, EventArgs e)
{
if (txt_Chinese.Text != string.Empty)//判断输入是否为空
{
try
{
txt_Num.Text = getCode(txt_Chinese.Text);
}
catch (IndexOutOfRangeException ex)
{
MessageBox.Show(ex.Message + "请输入正确的汉字", "出错!");
}
}
}
/// <summary>
/// 得到汉字区位码方法
/// </summary>
/// <param name="strChinese">汉字字符</param>
/// <returns>返回汉字区位码</returns>
public string getCode(string Chinese)
{
byte[] P_bt_array = Encoding.Default.GetBytes(Chinese);//得到汉字的Byte数组
int front = (short)(P_bt_array[0] - '\0');//将字节数组的第一位转换成short类型
int back = (short)(P_bt_array[1] - '\0');//将字节数组的第二位转换成short类型
return (front - 160).ToString() + (back - 160).ToString();//计算并返回区位码
}
}
}
输出带有双引号的字符串
class Program
{
static void Main(string[] args)
{
string value = string.Format("{0}-BW{1}MHz", "TMH", 10);
Console.WriteLine("字符串的值:"+"\"{0}\"",value);
Console.WriteLine("字符串的值:"+"\""+value+"\"");
Console.ReadLine();
}
}