13

我一直在研究一些代码。我有一个问题:强制转换、解析和转换之间有什么区别?我们什么时候可以使用它们?

4

7 回答 7

18

强制转换是当您获取一种类型的变量并将其更改为另一种类型时。您只能在某些情况下这样做,例如:

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

请注意,在这种情况下,转换是以强制转换的形式完成的。

解析是获取一个字符串并通过了解其内容将其转换为不同的类型。例如,将字符串“123”转换为数字 123,或将字符串“Saturday, September 22nd”转换为 DateTime。

于 2012-09-23T13:18:23.777 回答
10

Casting:告诉编译器一个对象实际上是别的东西而不改变它(尽管可能会导致一些数据丢失)。

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

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

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
于 2012-09-23T13:28:59.373 回答
3

这是三个具有特定用途的术语:

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

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

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 非常相关。

于 2012-09-23T13:20:35.547 回答
1

不同的人用它来表示不同的东西。在 .net 世界之外不必是真的,但这是我在阅读 Eric Lippert 的博客的 .net 上下文中所理解的:

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

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

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

  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,例如接受 astring并返回 a int

于 2013-11-29T12:25:58.760 回答
1

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

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 类实际上只是帮助您解析它

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

于 2012-09-23T13:20:23.063 回答
1

铸造:或解析

强制转换显式调用从一种类型到另一种类型的转换运算符。铸造变量并不简单。一组复杂的规则解决了强制转换。在某些情况下,数据会丢失,并且强制转换无法反转。在其他情况下,执行引擎中会引发异常。 int.Parse是一种最简单的方法,但它会在无效输入时引发异常。

尝试解析

int.TryParse是 C# 语言中解析整数的最有用的方法之一。此方法的工作方式与int.Parse. int.TryParse里面有try and catch结构。所以,它不会抛出异常

兑换:

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

许多程序员推荐使用TryParse代替Convert或。Cast

来源:www.dotnetperls.com

于 2012-09-23T13:49:47.433 回答
1

这个问题其实挺复杂的……

通常,强制转换只是告诉运行时将一种类型更改为另一种类型。这些必须是兼容的类型。例如 anint总是可以表示为 along所以可以将它转换为 a long。一些演员表有副作用。例如,float如果将 a 强制转换为 a ,则会降低其精度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).

解析是一些函数,它接受一种类型并返回另一种类型。它是一个实际的代码函数,而不仅仅是一个 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;
    }
}

我已经覆盖了显式转换运算符 for int,所以我现在可以这样做:

    public void OverridedCastExample()
    {
        CastableClass cc = new CastableClass {IntValue = 7};
        int i = (int)cc;
    }

看起来像一个普通的演员表,但实际上它调用了我在课堂上定义的方法。IL代码是:

call       int32 UnitTestProject1.CastableClass::op_Explicit(class UnitTestProject1.CastableClass)

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

于 2012-09-23T13:38:36.117 回答