前面介绍了整数、浮点数、字符和字符串的处理,实际开发工作中,不同类型的数据经常会相互转换,本文会讨论如何将其它类型转换为字符串,如何使用Convert类,以及如何使用值类型的Parse()和TryParse()方法进行类型转换,并将常用的转换操作封装到cfx/Str类。
需要将其它类型转换为字符串时,很多时候是可以自动完成的,如Console.WriteLine()方法,以及使用+运算符连接字符串和其它类型的数据等。需要注意布尔(bool)类型,true和false值转换为字符串形式分别是"True"和"False",这也是为什么在Console.WriteLine()方法中显示的true和false值总是True和False的原因。
将其它类型转换为字符串时,也可以调用对象(变量)的ToString()方法,方法会返回数据默认的字符串形式。此外,在自定义类型中也可以重写ToString()方法,并返回所需要的对象信息,如下面的代码。
using System; namespace csfx_demo { class Program { static void Main(string[] args) { Human tom = new Human() { Name = "Tom" }; Console.WriteLine(tom.ToString()); } } // class Human { public string Name { get; set; } // new public string ToString() { return "Human对象,Name(" + Name + ")"; } } }
代码中定义了Human类,并使用new关键字定义了新的ToString()方法,执行代码会显示“Human对象,Name(Tom)”。
Convert类定义在System命名空间,定义了一系列的类型转换方法,下面先来看ToInt32()方法的应用。
ToInt32()方法的功能是将各种类型的数据转换为32位有符号整数,即C#中的int类型和.NET Framework中的Int32类型。方法包含了一系列的重构版本,可以使用各种类型的参数,其中,对于字符串数据,还可以指定包含数据的进制(默认为十进制),如下面的代码。
using System; namespace csfx_demo { class Program { static void Main(string[] args) { Console.WriteLine(Convert.ToInt32("123")); // 123 Console.WriteLine(Convert.ToInt32("10",8)); // 8 Console.WriteLine(Convert.ToInt32("A", 16)); // 10 Console.WriteLine(Convert.ToInt32("11", 2)); // 3 } } }
ToInt32()方法会将null值转换为0,false值转换为0,true值转换为1,如下面的代码。
using System; namespace csfx_demo { class Program { static void Main(string[] args) { Console.WriteLine(Convert.ToInt32(null)); // 0 Console.WriteLine(Convert.ToInt32(false)); // 0 Console.WriteLine(Convert.ToInt32(true)); // 1 } } }
此外,当参数为浮点数时会对小数部分四舍五入,如122.56会转换为123。当参数内容不能转换为Int32类型(int)时,会抛出异常。
Convert.ToString()方法中,当参数一是整数时,可以使用参数二指定转换为指定进制格式的字符串,默认为十进制。下面的代码演示了相关应用。
using System; namespace csfx_demo { class Program { static void Main(string[] args) { Console.WriteLine(Convert.ToString(15)); // 15 Console.WriteLine(Convert.ToString(15, 2)); // 1111 Console.WriteLine(Convert.ToString(15, 8)); // 17 Console.WriteLine(Convert.ToString(15, 16)); // f } } }
需要注意的是,Convert.ToString()方法转换null时依然是null,true转换为"True",false转换为"False"。
Convert类中定义的ToXXX系列方法,其中的XXX为.NET Framework中的类型名,各个方法的重构版本中又可以设置各种类型的数据,如各种数值类型、string、bool、DateTime、object类型等,可以根据需要灵活应用。请注意,如果参数不能正确转换为目标类型数据会抛出异常。
各种值类型的Parse()方法可以将字符串类型转换为对应的类型,如int.Parse(s)会将字符串s的内容转换为int类型,如果转换失败会抛出异常,需要注意,包含浮点数的字符串也无法转换为整数。下面的代码代码演示了相关应用。
using System; namespace csfx_demo { class Program { static void Main(string[] args) { Console.WriteLine(int.Parse("123")); // 123 Console.WriteLine(int.Parse("122.56")); // 错误 Console.WriteLine(int.Parse("xyz")); // 错误 } } }
TryParse()方法会尝试将参数一的字符串内容转换为对应的类型,并通过参数二输出转换结果,方法会返回bool类型数据,成功转换返回true,否则返回false。下面的代码演示了相关应用。
using System; namespace csfx_demo { class Program { static void Main(string[] args) { int result; if(int.TryParse("123",out result)) { Console.WriteLine(result); } else { Console.WriteLine("转换失败"); } } } }
此代码会显示123,可以修改int.TryParse()方法第一个参数的内容来观察执行结果,如果字符串内容不能转换为int类型会显示“转换失败”,这里,浮点数格式的字符串内容同样不能转换为int类型。
各种数值类型、DateTime等类型都定义了Parse()和TryParse()方法,可以根据需要选择应用。
实际工作中,可能还需要各种数据转换逻辑,比如,对于在界面中输入的数据可以尝试转换为指定类型,如果转换失败就使用默认值。下面的代码,在cfx/Str.cs文件中创建Str类,并创建ToInt()静态方法。
using System; using System.Text.RegularExpressions; namespace cfx { public static class Str { // 转换为int类型,默认值为0 public static int ToInt(this string s, int defVal = 0) { int result; if (int.TryParse(s, out result)) return result; else return defVal; } } }
代码中,在cfx命名空间里创建了Str静态类,其中定义了ToInt()静态方法,其中,参数一指定需要转换为int类型的字符串内容,参数二指定转换失败后返回的默认值;方法会返回int类型的数据。方法中调用了int类型的TryParse()方法执行转换,转换成功返回转换结果,否则返回默认值。
此外,请注意ToInt()方法的第一个参数使用了this关键字,也就是将ToInt()方法定义为string类型的扩展方法。下面的代码演示了Str.ToInt()方法的应用。
using System; using cfx; namespace csfx_demo { class Program { static void Main(string[] args) { Console.WriteLine("123".ToInt()); // 123 Console.WriteLine(Str.ToInt("123")); // 123 Console.WriteLine("xyz".ToInt()); // 0 Console.WriteLine("xyz".ToInt(-1)); // -1 } } }
cfx.Str类中,为什么将ToInt()方法的第一个参数设置为string类型呢?
应用开发中,如Web项目中,各种字段(Web控件)中获取的数据大多是文本类型,所以,将文本转换为所需的类型就显得格外重要,也最常见。当然,在实际工作中,如果需要更多的转换逻辑,也可以创建相应的转换方法,如果不想创建过多的重构版本,可以通过object类型创建通用操作方法,如下面的代码(cfx/Obj.cs)。
using System; namespace cfx { public static class Obj { // 转换为int类型,默认值为0 public static int ToInt(object obj, int defVal = 0) { int result; if (obj != null && int.TryParse(obj.ToString(), out result)) return result; else return defVal; } } }
在Obj.ToInt()方法,参数一指定为object类型,这里没有使用this关键字,原因是object是所有类型的终极基类,在object类型上添加扩展方法并不是一个好主意。参数二同样指定默认值。方法中,多了参数一是否为null值的判断条件,如果是null值则返回默认值,如果不是,则判断其字符串格式的数据是否能够转换为int类型,转换成功返回转换数据,否则返回默认值。下面的代码演示了相关应用。
using System; using cfx; namespace csfx_demo { class Program { static void Main(string[] args) { Console.WriteLine(Obj.ToInt("123")); // 123 Console.WriteLine(Obj.ToInt("xyz")); // 0 Console.WriteLine(Obj.ToInt("xyz", -1)); // -1 } } }
Str和Obj类中可以根据需要封装一些常用类型的转换方法,下面的代码给出了Str类型的一些代码,可以参考使用。
using System; using System.Text.RegularExpressions; namespace cfx { public static class Str { // 转换为int类型,默认值为0 public static int ToInt(this string s, int defVal = 0) { int result; if (int.TryParse(s, out result)) return result; else return defVal; } // public static uint ToUInt(this string s, uint defVal = 0) { uint result; if (uint.TryParse(s, out result)) return result; else return defVal; } // public static long ToLng(this string s, long defVal = 0L) { long result; if (long.TryParse(s, out result)) return result; else return defVal; } // public static ulong ToULng(this string s, ulong defVal = 0L) { ulong result; if (ulong.TryParse(s, out result)) return result; else return defVal; } // public static float ToSng(this string s, float defVal = 0F) { float result; if (float.TryParse(s, out result)) return result; else return defVal; } // public static double ToDbl(this string s, double defVal = 0D) { double result; if (double.TryParse(s, out result)) return result; else return defVal; } // public static decimal ToDec(this string s, decimal defVal = 0M) { decimal result; if (decimal.TryParse(s, out result)) return result; else return defVal; } } }