C#教程 - 数据类型转换(Type Conversion)
更新记录
转载请注明出处。
2022年9月11日 发布。
2022年9月10日 从笔记迁移到博客。
说明
将某个值的类型从A转为B
隐式转换(Implicit type conversion)
说明:
类型兼容情况下才会发生隐式转换
隐式转换发生在类型兼容并且小内存转大内存的情况
以下预定义类型转换会发生隐式转化:
显式转化和强制转换(Explicit type conversion)
说明
显式转换 和 强制转换 在程序员需要对自己的行为负责的情况下进行
以下预定义类型转换需要使用显式转换:
转换出错将会抛出异常:
转换不成功将抛出InvalidCastException异常
数值转换中溢出将抛出OverflowException异常
显式字符串转为其他类型方法1使用静态方法:Parse
目标类型.Parse(要转换的字符串);
注意:该方法如果转换不成功会抛出异常
注意:如果字符串无法解析为数值将抛出System.FormatException异常
实例:
try
{
double target1 = double.Parse("3.14159274");
decimal target2 = decimal.Parse("AAA");
}
catch(FormatException e)
{
Console.WriteLine(e.Message);
}
显式字符串转为其他类型方法2使用静态方法:TryParse
类型.TryParse(要转换的字符串,out 目标类型变量);
注意:如果转换不成功将赋值给目标类型变量默认值
实例:
double target1;
decimal target2;
double.TryParse("3.14159274",out target1);
decimal.TryParse("3.14159274",out target2);
实例:使用tryParse返回值做条件
int count;
string input = Console.ReadLine();
if (int.TryParse(input, out count))
{
WriteLine($"There are {count} eggs.");
}
else
{
WriteLine("I could not parse the input.");
}
数值转为十六进制字符串
int i = 16;
Console.WriteLine(i.ToString("x"));
十六进制字符串转为数值
string hexString = "FF";
int number = int.Parse(hexString, System.Globalization.NumberStyles.HexNumber);
Console.WriteLine(number);
字符串转为字符数组
string textString = "Panda66";
char[] charArray = textString.ToCharArray();
强制转换
(目标类型)表达式
实例:
unchecked
{
byte target = (byte)123123123;
Console.WriteLine(target);//179
}
转换分类
对于自定义类型,用户可以自定义隐式和显式转化
装箱和拆箱(Boxing and Unboxing)
可以使用 装箱 和 拆箱 进行转换,对应中间类型:System.Object、System.ValueType
装箱转换:
拆箱转化:
装箱后仍然可以获得值的Type类型来确定其真实类型
实例:
object abc = 123;
Console.WriteLine($"{abc.GetType()}"); //System.Int32
注意:装箱和拆箱发生在值类型和引用类型之间,其他类型不可以
//引用转换
object[] a1 = new String[3];
//这是不可以的
object[] a2 = new int[3]; //error
注意:装箱执行的是值复制
int i = 3;
object boxed = i;
i = 5;
Console.WriteLine (boxed); // 3
数值转换
数值的转换可以是 显式 也可以是 隐式 的
占用内存较小的类型 可以 隐式转换 为 占用内存较大的类型
对于 占用内存较大的类型 转为 占用内存较小的类型 需要使用 显式转换
注意:Char类型与数值进行转换需要使用强制转换
数值转换的几种方法(Numbers Conversions)
检测数值溢出
数值转换会出现溢出的情况,使用checked运算符可以处理溢出情况
如果转换代码不使用checked检测,则溢出不会被处理,代码继续执行
如果转换代码使用checked检测,存在溢出就抛出OverflowException异常
默认情况下是不进行检测溢出的
使用unchecked运算符会忽略溢出检查
使用方法:
checked(表达式);
unchecked(表达式);
除了这种用法,还可以使用大括号语法:
checked
{
bool test1 = Convert.ToBoolean("true");
bool test2 = Convert.ToBoolean(0);
bool test3 = Convert.ToBoolean(-1);
}
还可以进行嵌套:
checked
{
bool test1 = Convert.ToBoolean("true");
bool test2 = Convert.ToBoolean(0);
unchecked
{
bool test3 = Convert.ToBoolean(-1);
}
}
注意:checked只能用于整数类型,用于float、double类型无效
注意:checked对decimal无效,因为decimal类型总是会进行类型溢出检查
is运算符
默认情况下,转换不成功将抛出InvalidCastException异常,使用is运算符检测,可以避免抛出异常
使用格式:
对象 is 类/接口
Tom is Person //返回一个boolean值
is运算符只能用于引用转换、装箱转换、拆箱转换,不可以用于用户自定义转换
is运算符和C#模式匹配(C# 7可用)
即在is匹配时声明变量
实例1:
string test = "Panda666.com";
if(test is string result)
{
Console.WriteLine(result);
}
实例2:
string test = "Panda666.com";
if(test is string result && result == "Panda666.com")
{
Console.WriteLine(result);
}
as运算符
as运算符和强制转换类似,但不抛出异常
如果转换失败,返回null,而不是抛出异常
as运算符常用于对象向上和向下转换
使用格式:
对象 as 类/接口
Tom as Person //返回对象或null
as运算符转换后使用前,记得检测是否为null
as运算符只能用于引用转换和装箱转换,不可以用于自定义转换或转为值类的转换
值类型有意思的地方
C#的所有值类型均隐式派生自System.ValueType,而System.ValueType直接派生于System.Object
即System.ValueType本身是一个类类型,而不是值类型
其关键在于ValueType重写Equals()方法,从而对值类型按照实例的值来比较,而不是引用地址来比较
引用类型转换(Reference Conversions)
引用类型转换说明
分为向上(Upcasting)转换 和 向下(Downcasting)转换
Implicitly upcast to a base class reference
Explicitly downcast to a subclass reference
注意:如果向下转换失败,会抛出InvalidCastException异常
向上(Upcasting)转换
向上(Upcasting)转换是指子类转为父类的引用
这是隐式(Implicitly upcast)转换的
实例:
using System;
namespace ConsoleApp1
{
/// <summary>
/// 父类
/// </summary>
class FatherClass { }
/// <summary>
/// 子类
/// </summary>
class SonClass : FatherClass { }
class Program
{
static void Main(string[] args)
{
//隐式转换
FatherClass sonClass = new SonClass();
//wait
Console.ReadKey();
}
}
}
向下(Downcasting)转换
向下(Downcasting)转换是父类转为子类
这是显式(Explicitly downcast)转换的
注意:如果转换向下转换失败,运行时将会抛出(InvalidCastException )
实例:
using System;
namespace ConsoleApp1
{
/// <summary>
/// 父类
/// </summary>
class FatherClass { }
/// <summary>
/// 子类
/// </summary>
class SonClass : FatherClass { }
class Program
{
static void Main(string[] args)
{
//隐式转换(子类转为父类)
FatherClass sonClass = new SonClass();
//显式转换(父类转为子类)
SonClass sonClass2 = (SonClass)sonClass;
//wait
Console.ReadKey();
}
}
}
可以使用as运算符(as operator)和is运算符(is operator)避免运行时抛出异常
实例:
using System;
namespace ConsoleApp1
{
/// <summary>
/// 父类
/// </summary>
class FatherClass { }
/// <summary>
/// 子类
/// </summary>
class SonClass : FatherClass { }
class Program
{
static void Main(string[] args)
{
//隐式转换(子类转为父类)
FatherClass sonClass = new SonClass();
//显式转换(父类转为子类)
SonClass result = sonClass as SonClass;
if (result != null)
{
Console.WriteLine(result);
}
//wait
Console.ReadKey();
}
}
}
从C# 7开始可以直接在is运算符中定义变量
实例:
using System;
namespace ConsoleApp1
{
/// <summary>
/// 父类
/// </summary>
class FatherClass { }
/// <summary>
/// 子类
/// </summary>
class SonClass : FatherClass { }
class Program
{
static void Main(string[] args)
{
//隐式转换(子类转为父类)
FatherClass sonClass = new SonClass();
//显式转换(父类转为子类)
if (sonClass is SonClass result)
{
Console.WriteLine(result);
}
//wait
Console.ReadKey();
}
}
}
数值类型四舍五入问题
如果小数部分小于0.5,则始终向下取整
如果小数部分大于0.5,则始终向上取整
如果小数部分是0.5,非小数部分是奇数,则向上舍入;如果非小数部分是偶数,则向下舍入
Console.WriteLine(Math.Round(10.6));//11
Console.WriteLine(Math.Round(10.4));//10
Console.WriteLine(Math.Round(10.5));//10
Console.WriteLine(Math.Round(10.5, MidpointRounding.ToPositiveInfinity)); //11
ToString()与Parse()/TryParse()方法
ToString()方法将类型转为字符串类型
Parse()/TryParse()静态方法将字符串类型转为具体的类型
注意:Parse()静态方法如果转换失败,会抛出FormatException异常
注意:ToString/Parse/TryParse方法默认基于本地文化进行转换,可以设置文化类型
实例:
string s = true.ToString(); // s = "True"
bool b = bool.Parse(s); // b = true
实例:
```c#
bool failure = int.TryParse("qwerty", out int i1);
bool success = int.TryParse("123", out int i2);
实例:
bool success = int.TryParse ("123", out int _);
实例:
double x = double.Parse ("1.234", CultureInfo.InvariantCulture);
实例:
double x = double.Parse ("1.234", CultureInfo.InvariantCulture);
实例:
string x = 1.234.ToString (CultureInfo.InvariantCulture);
Convert静态类型
说明
Convert静态类型的作用:
Real-to-integral conversions that round rather than truncate
Parsing numbers in base 2, 8, and 16
Dynamic conversions
Base-64 translations
使用Convert静态类型强化转换
注意:转换不成功将抛出System.FormatException异常
注意:Convert还可以用于日期转换
实例:
try
{
bool panda1 = Convert.ToBoolean("true");
int panda2 = Convert.ToInt32("666");
decimal panda3 = Convert.ToDecimal("3.14156");
Console.WriteLine(panda1); //true
Console.WriteLine(panda2); //666
Console.WriteLine(panda3); //3.14156
}
catch(FormatException e)
{
Console.WriteLine(e.Message);
}
进制转换
实例:转为十六进制
int thirty = Convert.ToInt32 ("1E", 16); // Parse in hexadecimal
实例:转为二进制
uint five = Convert.ToUInt32 ("101", 2); // Parse in binary
byte[]与Base64转换(Base-64 conversions)
转为Base64编码字符串
string ToBase64String(byte[] inArray);
string ToBase64String(byte[] inArray, int offset, int length);
使用将Base64编码字符串转为原始值
byte[] FromBase64CharArray(char[] inArray, int offset, int length);
byte[] FromBase64String(string s);
实例:
//原始数据
byte[] someDate = new byte[]
{
1,2,3,4,5,6
};
//转换Base64编码字符串
string base64String = Convert.ToBase64String(someDate);
//转为原始数据
byte[] originData = Convert.FromBase64String(base64String);
foreach (var item in originData)
{
Console.WriteLine(item);
}
IFormattable接口
接口的定义
public interface IFormattable
{
string ToString (string format, IFormatProvider formatProvider);
}
说明:
所有的数值类型都实现了IFormatable接口
.NET Core中预定义了NumberFormatInfo、DateTimeFormatInfo、CultureInfo
ToString方法的第一个参数是字符串格式(format string)
ToString方法的第二个参数是格式提供器(format provider)
实例:使用预定义的数值格式化提供器设置货币的符号
NumberFormatInfo f = new NumberFormatInfo();
f.CurrencySymbol = "$$";
Console.WriteLine (3.ToString ("C", f)); // $$ 3.00
实例:使用预定义的数值格式化提供器设置分隔符
NumberFormatInfo f = new NumberFormatInfo ();
f.NumberGroupSeparator = " ";
Console.WriteLine (12345.6789.ToString ("N3", f)); // 12 345.679
实例:设置文化类型
CultureInfo uk = CultureInfo.GetCultureInfo ("en-GB");
Console.WriteLine (3.ToString ("C", uk)); // £3.00
实例:设置文化无关(based on American culture)
DateTime dt = new DateTime (2000, 1, 2);
CultureInfo iv = CultureInfo.InvariantCulture;
Console.WriteLine (dt.ToString (iv)); // 01/02/2000 00:00:00
Console.WriteLine (dt.ToString ("d", iv)); // 01/02/2000
预定义标准数字格式字符串(standard numeric format strings)
自定义标准数值格式字符串(Custom numeric format strings)
预定义日期格式化字符串(Date/Time Format Strings)
实例:
DateTime datetime = DateTime.Now;
Console.WriteLine(datetime.ToString("d")); //2021/2/17
Console.WriteLine(datetime.ToString("t")); //11:06
Console.WriteLine(datetime.ToLongDateString()); //2021年2月17日
Console.WriteLine(datetime.ToLongTimeString()); //11:06:06
Console.WriteLine(datetime.ToShortDateString()); //2021/2/17
Console.WriteLine(datetime.ToShortTimeString()); //11:06
不分区域的日期字符串格式字符串(Culture-insensitive date/time format strings)
XmlConvert用于格式化和解析XML
所在命名空间
using System.Xml;
BitConverter
BitConverter用于二进制转换
实例:
foreach (byte b in BitConverter.GetBytes(3.5))
{
Console.Write(b + " "); // 0 0 0 0 0 0 12 64
}
动态类型转换(Dynamic conversions)
适合于在运行时才知道类型的场景
使用Convert静态类型的ChangeType静态方法
实例:动态类型转换
Type targetType = typeof (int);
object source = "42";
object result = Convert.ChangeType (source, targetType);
Console.WriteLine (result); // 42
Console.WriteLine (result.GetType()); // System.Int32
本文来自博客园,作者:重庆熊猫,转载请注明原文链接:https://www.cnblogs.com/cqpanda/p/16677268.html