铸造,解析和转换之间的区别

我一直在研究一些代码。 我有一个问题:铸造,解析和转换有什么区别? 当我们可以使用它们?

转换是指您获取一种类型的变量并将其更改为其他类型。 你只能在某些情况下这样做,如下:

string str = "Hello"; object o = str; string str2 = (string)o; // <-- This is casting 

转换不会更改变量的值 - 值保持相同的类型(字符串“Hello”)。

转换是指从一种类型中获取并将其转换为其他类型时:

  double d = 5.5; int i = (int)d; // <---- d was converted to an integer 

请注意,在这种情况下,转换是以铸造的forms完成的。

解析是通过理解其内容来获取字符串并将其转换为其他类型。 例如,将字符串“123”转换为数字123,或将字符串“Saturday,September 22nd”转换为DateTime。

转换 :告诉编译器一个对象确实是别的而不改变它(虽然可能会导致一些数据丢失)。

 object obj_s= "12345"; string str_i = (string) obj; // "12345" as string, explicit int small = 12345; long big = 0; big = small; // 12345 as long, implicit 

解析 :告诉程序解释(在运行时)字符串。

 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 

这三个术语各有特定用途:

  • 铸造 – 将一种type改为另一种。 为此,类型必须兼容int – > object ; IList – > IEnumerable
  • 解析 – 通常是指读取字符串并提取有用的部分
  • 转换 – 类似于转换,但通常转换涉及将一种类型更改为其他不兼容的类型。 一个例子是将对象转换为字符串。

从一种类型到另一种类型的强制转换需要某种forms的兼容性,通常是通过inheritance或实现接口。 转换可以是隐式的或显式的:

 class Foo : IFoo { // implementations } // implicit cast public IFoo GetFoo() { return Foo; } // explicit cast public IFoo GetFoo() { return Foo as IFoo; } 

有很多方法可以解析。 我们读到了关于XML解析的内容; 有些类型有ParseTryParse方法; 然后我们有时需要解析字符串或其他类型来提取“我们关心的东西”。

 int.Parse("3") // returns an integer value of 3 int.TryParse("foo", out intVal) // return true if the string could be parsed; otherwise false 

转换可能需要将一种类型更改为另一种类型不兼容的类型。 这也可能涉及一些解析。 转换示例通常是IMO,它与特定的上下文密切相关。

转换(转换为需要兼容的类型)数据类型之间的转换可以使用强制转换显式完成

 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. } 

解析(解析是不同类型之间的转换:)将一种类型转换为另一种类型可以称为解析uisng int.parse

 int num = int.Parse("500"); 

遍历XML之类的数据项也可以称为解析

当涉及用户定义的转换时,这通常需要返回不同的对象/值。 用户定义的转换通常存在于值类型而不是引用类型之间,因此这很少成为问题。

转换使用Convert-class实际上只是帮助您解析它

有关更多信息,请参阅http://msdn.microsoft.com/en-us/library/ms228360%28VS.80%29.aspx

这个问题其实非常复杂……

通常, 强制转换只是告诉运行时将一种类型更改为另一种类型。 这些必须是兼容的类型。 例如, int总是可以表示为long因此可以将其强制转换为long 。 有些演员有副作用。 例如,如果将其转换为int ,则float将降低其精度。 因此(int)1.5f将导致int值1.转换通常是更改类型的最快方式,因为它是单个IL运算符。 例如,代码:

  public void CastExample() { int i = 7; long l = (long)i; } 

通过运行IL代码执行强制转换:

 conv.i8 //convert to 8-byte integer (aka Int64, aka long). 

解析是一些函数,它接受一次类型并返回另一个。 它是一个实际的代码函数,而不仅仅是一个IL运算符。 这通常需要更长的时间才能运行,因为它运行多行代码。

例如,这段代码:

  public void ParseExample() { string s = "7"; long l = long.Parse(s); } 

运行IL代码:

 call int64 [mscorlib]System.Int64::Parse(string) 

换句话说,它称为实际方法。 在内部,Int64类型提供了该方法:

  public static long Parse(String s) { return Number.ParseInt64(s, NumberStyles.Integer, NumberFormatInfo.CurrentInfo); } 

和Number.Parse:

  [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) 

所以无论如何,你通常想尽可能地施展。 然后解析,如果你不能。

铸造:或解析

强制转换显式地将转换运算符从一种类型调用到另一种类型。 转换变量并不简单。 一组复杂的规则可以解决强制转换问题。 在某些情况下,数据会丢失,并且无法撤消演员表。 在其他情况下,执行引擎中会引发exception。 int.Parse是一个最简单的方法,但它会在无效输入上抛出exception。

的TryParse

int.TryParse是用于解析C#语言中的整数的最有用的方法之一。 此方法的工作方式与int.Parse相同。 int.TryParse尝试并捕获内部结构。 所以,它不会抛出exception

兑换:

将基本数据类型转换为另一种基本数据类型。 Convert.ToInt32及其兄弟Convert.ToInt16和Convert.ToInt64实际上是int.Parse方法的静态包装器方法。

许多程序员推荐使用TryParse而不是ConvertCast

来源: http://www.dotnetperls.com

不同的人用它来表示不同的东西。 在.net世界之外它不一定是真的,但这里是我在.net上下文中读到的Eric Lippert的博客:

从一种forms到另一种forms的所有类型转换都可以称为转换 。 一种分类方法可能是

  1. 隐含的 –

    一个。 表示变化 (也称为强制)

     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 l = new List(); 

    仅对引用类型有效,永远不会更改正在转换的对象的引用标识,转换始终成功,在编译时保证,无运行时检查。

  2. 显式 (也称为铸造) –

    一个。 表示变化

     int i = 0; enum e = (enum)i; object o = i; i = (int)o; // (specifically called unboxing conversion) 

    需要显式转换运算符,更改正在转换的对象的引用标识,转换可能成功也可能不成功,运行时检查兼容性。

    表示保留 (也称为显式引用转换)

      object o = ""; string s = (string)o; 

    仅对引用类型有效,永远不会更改正在转换的对象的引用标识,转换可能成功也可能不成功,运行时检查兼容性。

虽然转换是语言级构造,但是Parse在框架级别的意义上是一个非常不同的东西,换句话说,它们是为了从输入获取输出而编写的自定义方法 ,比如int.Parse ,它接受一个string并返回一个int