C# 转换、解析和转换之间的区别
我已经在编写一些代码一段时间了。我有一个问题:转换、解析和转换之间有什么区别?我们什么时候可以使用它们?强制转换是指将一种类型的变量更改为另一种类型。您只能在某些情况下这样做,例如:C# 转换、解析和转换之间的区别,c#,C#,我已经在编写一些代码一段时间了。我有一个问题:转换、解析和转换之间有什么区别?我们什么时候可以使用它们?强制转换是指将一种类型的变量更改为另一种类型。您只能在某些情况下这样做,例如: string str = "Hello"; object o = str; string str2 = (string)o; // <-- This is casting string str=“你好”; 对象o=str; 字符串str2=(字符串)o;// 铸造 (铸造工作类型需要兼容) 可以使用强制转
string str = "Hello";
object o = str;
string str2 = (string)o; // <-- This is casting
string str=“你好”;
对象o=str;
字符串str2=(字符串)o;// 铸造
(铸造工作类型需要兼容)
可以使用强制转换显式地在数据类型之间进行转换
static void _Casting()
{
int i = 10;
float f = 0;
f = i; // An implicit conversion, no data will be lost.
f = 0.5F;
i = (int)f; // An explicit conversion. Information will be lost.
}
解析(解析是不同类型之间的转换:)
将一种类型转换为另一种类型可以称为parsing uisng int.parse
int num = int.Parse("500");
遍历XML等数据项也可以称为解析
当涉及用户定义的转换时,通常需要返回不同的对象/值。用户定义的转换通常存在于值类型之间,而不是引用类型之间,因此这很少是一个问题
转换
使用Convert类实际上只是帮助您解析它
有关更多信息,请参阅以下三个术语,每个术语都有特定用途:
- 铸造-将一种
类型更改为另一种类型。为了做到这一点
类型必须兼容:int
->object
<代码>IList
->IEnumerable
- 解析-通常指读取字符串和提取有用部分
- 转换-类似于强制转换,但通常转换会涉及将一种类型更改为其他不兼容的类型。例如,将对象转换为字符串
从一种类型转换到另一种类型需要某种形式的兼容性,通常通过接口的继承或实现。强制转换可以是隐式的,也可以是显式的:
class Foo : IFoo {
// implementations
}
// implicit cast
public IFoo GetFoo() {
return Foo;
}
// explicit cast
public IFoo GetFoo() {
return Foo as IFoo;
}
有很多方法可以解析。我们阅读了XML解析;有些类型有Parse
和TryParse
方法;有时我们需要解析字符串或其他类型来提取“我们关心的东西”
int.Parse("3") // returns an integer value of 3
int.TryParse("foo", out intVal) // return true if the string could be parsed; otherwise false
转换可能需要将一种类型更改为另一种不兼容的类型。这也可能涉及一些解析。在我看来,转换示例通常与特定上下文紧密相关。强制转换:告诉编译器某个对象实际上是另一个对象,而不改变它(尽管可能会导致某些数据丢失)
解析:告诉程序(在运行时)解释字符串
string int_s = "12345";
int i = int.Parse(int_s); // 12345 as int
转换:告诉程序使用内置方法尝试更改可能无法简单互换的类型
double dub = 123.45;
int i = System.Convert.ToInt32(dub); // 123 as int
这个问题其实很复杂
通常,强制转换只是告诉运行时将一种类型更改为另一种类型。这些必须是兼容的类型。例如,int
始终可以表示为long
,因此可以将其转换为long
。有些石膏有副作用。例如,如果将float
转换为int
,则其精度将下降。因此(int)1.5f
将导致int值1。强制转换通常是更改类型的最快方法,因为它是单个IL运算符。例如,代码:
public void CastExample()
{
int i = 7;
long l = (long)i;
}
通过运行IL代码执行强制转换:
conv.i8 //convert to 8-byte integer (a.k.a. Int64, a.k.a. long).
call int64 [mscorlib]System.Int64::Parse(string)
解析是一个函数,它接受一个类型并返回另一个类型。它是一个实际的代码函数,而不仅仅是一个IL运算符。这通常需要更长的时间来运行,因为它运行多行代码
例如,此代码:
public void ParseExample()
{
string s = "7";
long l = long.Parse(s);
}
运行IL代码:
conv.i8 //convert to 8-byte integer (a.k.a. Int64, a.k.a. long).
call int64 [mscorlib]System.Int64::Parse(string)
换句话说,它调用一个实际的方法。在内部,Int64类型提供了该方法:
public static long Parse(String s) {
return Number.ParseInt64(s, NumberStyles.Integer, NumberFormatInfo.CurrentInfo);
}
和编号。解析:
[System.Security.SecuritySafeCritical] // auto-generated
internal unsafe static Int64 ParseInt64(String value, NumberStyles options, NumberFormatInfo numfmt) {
Byte * numberBufferBytes = stackalloc Byte[NumberBuffer.NumberBufferBytes];
NumberBuffer number = new NumberBuffer(numberBufferBytes);
Int64 i = 0;
StringToNumber(value, options, ref number, numfmt, false);
if ((options & NumberStyles.AllowHexSpecifier) != 0) {
if (!HexNumberToInt64(ref number, ref i)) {
throw new OverflowException(Environment.GetResourceString("Overflow_Int64"));
}
}
else {
if (!NumberToInt64(ref number, ref i)) {
throw new OverflowException(Environment.GetResourceString("Overflow_Int64"));
}
}
return i;
}
等等。。。所以你可以看到它实际上在做很多代码
现在情况变得更复杂的是,尽管强制转换通常最快,但类可以重写隐式和显式强制转换操作符。例如,如果我编写类:
public class CastableClass
{
public int IntValue { get; set; }
public static explicit operator int(CastableClass castable)
{
return castable.IntValue;
}
}
我已经覆盖了int
的显式强制转换运算符,因此现在可以执行以下操作:
public void OverridedCastExample()
{
CastableClass cc = new CastableClass {IntValue = 7};
int i = (int)cc;
}
这看起来像一个普通的强制转换,但实际上它调用了我在类中定义的方法。IL代码为:
call int32 UnitTestProject1.CastableClass::op_Explicit(class UnitTestProject1.CastableClass)
所以不管怎么说,你通常希望在任何时候都可以施展才华。如果不能,则进行解析。或解析
强制转换显式地调用从一种类型到另一种类型的转换运算符。
铸造变量并不简单。一组复杂的规则解决强制类型转换。在某些情况下,数据丢失,且无法反转转换。在其他情况下,执行引擎会引发异常。
int.Parse
是一种最简单的方法,但它会对无效输入抛出异常
int.TryParse
是C#语言中解析整数最有用的方法之一。此方法的工作方式与int.Parse
相同。
int.TryParse
内部具有try-and-catch结构。因此,它不会抛出异常
将基本数据类型转换为其他基本数据类型。
Convert.ToInt32及其同级Convert.ToInt16和Convert.ToInt64实际上是int.Parse方法的静态包装器方法
许多程序员建议使用TryParse
而不是Convert
或Cast
来源:不同的人用它来表达不同的意思。在.net世界之外,这不一定是真的,但以下是我在.net环境下阅读Eric Lippert的博客时所理解的:
从一种形式到另一种形式的所有类型转换都可以称为转换。一种分类方法可能是
隐式-
a表示改变(也称为强制)
需要隐式转换运算符,转换始终成功(隐式转换运算符不应抛出),更改正在转换的对象的引用标识
b表示保留(也称为隐式引用转换)
需要显式转换运算符ch
int i = 0;
double d = i;
object o = i; // (specifically called boxing conversion)
IConvertible o = i; // (specifically called boxing conversion)
string s = "";
object o = s;
IList<string> l = new List<string>();
int i = 0;
enum e = (enum)i;
object o = i;
i = (int)o; // (specifically called unboxing conversion)
object o = "";
string s = (string)o;