C# 转换和使用 Convert.To() 方法之间的区别
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15394032/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Difference between casting and using the Convert.To() method
提问by
I have a function that casts a double
on string
values.
我有一个double
对string
值进行转换的函数。
string variable = "5.00";
double varDouble = (double)variable;
A code change was checked in and the project builds with the error: System.InvalidCastException: Specified cast is not valid.
已签入代码更改,并且项目构建时出现错误: System.InvalidCastException: Specified cast is not valid.
However, after doing the following...
但是,在执行以下操作后...
string variable = "5.00";
double varDouble = Convert.ToDouble(variable);
...the project builds without any errors.
...项目构建没有任何错误。
What is the difference between casting and using the Convert.To()
method?Why does casting throw an Exception
and using the Convert.To()
does not?
铸造和使用Convert.To()
方法有什么区别?为什么铸造会抛出一个Exception
而使用Convert.To()
则不会?
采纳答案by Adriano Repetti
Even if you maysee them somehow as equivalent they're completely different in purpose. Let's first try to define what a cast is:
即使您可能以某种方式将它们视为等效,但它们的目的完全不同。让我们首先尝试定义演员表是什么:
Casting is the action of changing an entity of one data type into another.
强制转换是将一种数据类型的实体更改为另一种数据类型的操作。
It's little bit generic and it's somehow equivalent to a conversionbecause cast often has the same syntax of a conversion so the question should be when a cast (implicit or explicit) is allowed by the language and when do you have to use a (more) explicit conversion?
它有点通用,它在某种程度上等同于转换,因为转换通常具有相同的转换语法,因此问题应该是语言何时允许转换(隐式或显式)以及何时必须使用(更多)显式转换?
Let me first drawa simple line between them. Formally (even if equivalent for language syntax) a cast will change type while a conversion will/may change value (eventually togetherwith type). Also a cast is reversible while conversion may not be.
让我先在它们之间划一条简单的线。正式地(即使语言语法等效),强制转换将更改类型,而转换将/可能会更改值(最终与类型一起)。此外,演员表是可逆的,而转换可能不是。
This topic is pretty vast so let's try to narrow a little bit by excluding custom cast operators from the game.
这个话题非常广泛,所以让我们尝试通过从游戏中排除自定义转换运算符来缩小范围。
Implicit casts
隐式转换
In C# a cast is implicit when you won't lose any information(please note that this check is performed with types and not with their actual values).
在 C# 中,当您不会丢失任何信息时,强制转换是隐式的(请注意,此检查是使用类型而不是它们的实际值执行的)。
Primitive types
原始类型
For example:
例如:
int tinyInteger = 10;
long bigInteger = tinyInteger;
float tinyReal = 10.0f;
double bigReal = tinyReal;
These casts are implicit because during the conversion you won't lose any information (you just make the type wider). Vice versa implicit cast isn't allowed because, regardless their actual values (because they can be checked only at run-time), during conversion you may lose some information. For example this code won't compile because a double
may contain (and actually it does) a value not representable with a float
:
这些强制转换是隐式的,因为在转换过程中你不会丢失任何信息(你只是让类型更宽)。反之亦然,不允许隐式转换,因为无论它们的实际值如何(因为它们只能在运行时检查),在转换过程中您可能会丢失一些信息。例如,此代码将无法编译,因为 adouble
可能包含(实际上它确实包含)无法用 a 表示的值float
:
// won't compile!
double bigReal = Double.MaxValue;
float tinyReal = bigReal;
Objects
对象
In case of an object (a pointer to) the cast is always implicit when the compiler can be sure that the source type is a derived class (or it implements) the type of the target class, for example:
在对象(指向的指针)的情况下,当编译器可以确定源类型是派生类(或它实现)目标类的类型时,转换总是隐式的,例如:
string text = "123";
IFormattable formattable = text;
NotSupportedException derivedException = new NotSupportedException();
Exception baseException = derivedException;
In this case the compiler knowsthat string
implements IFormattable
and that NotSupportedException
is (derives from) Exception
so the cast is implicit. No information is lost because objects doesn't change their types (this is different with struct
s and primitive types because with a cast you create a new object of another type), what changes is your viewof them.
在这种情况下,编译器知道是string
工具IFormattable
和NotSupportedException
是(派生自)Exception
这样的转换是隐含的。没有信息丢失,因为对象不会改变它们的类型(这与struct
s 和原始类型不同,因为使用强制转换您创建了另一种类型的新对象),改变的是您对它们的看法。
Explicit casts
显式转换
A cast is explicit when the conversion isn't done implicitly by the compiler and then you must use the cast operator. Usually it means that:
当转换不是由编译器隐式完成时,强制转换是显式的,然后您必须使用强制转换运算符。通常它的意思是:
- You may lose information or data so you have to be aware of it.
- Conversion may fail (because you can't convert one type to the other) so, again, you must be aware of what you're doing.
- 您可能会丢失信息或数据,因此您必须意识到这一点。
- 转换可能会失败(因为您无法将一种类型转换为另一种类型),因此,您必须再次了解自己在做什么。
Primitive types
原始类型
An explicit cast is required for primitive types when during conversion you may lose some data, for example:
当在转换期间您可能会丢失一些数据时,原始类型需要显式转换,例如:
double precise = Math.Cos(Math.PI * 1.23456) / Math.Sin(1.23456);
float coarse = (float)precise;
float epsilon = (float)Double.Epsilon;
In both examples, even if values fall within the float
range, you'll lose information (in this case precision) so the conversion must be explicit. Now try this:
在这两个示例中,即使值在float
范围内,您也会丢失信息(在本例中为精度),因此转换必须是显式的。现在试试这个:
float max = (float)Double.MaxValue;
This conversion will fail so, again, it must be explicit so you're aware of it and you may do a check (in the example value is constant but it may come from some run-time computations or I/O). Back to your example:
此转换将失败,因此,再次,它必须是显式的,因此您知道它并且您可以进行检查(在示例中值是常量,但它可能来自某些运行时计算或 I/O)。回到你的例子:
// won't compile!
string text = "123";
double value = (double)text;
This won't compile because compiler can't convert text to numbers. Text may contains any characters, not numbers only and this is too much, in C#, even for an explicit cast (but it may be allowed in another language).
这不会编译,因为编译器无法将文本转换为数字。文本可以包含任何字符,而不仅仅是数字,这在 C# 中太多了,即使对于显式转换也是如此(但在其他语言中可能允许)。
Objects
对象
Conversion from pointers (to objects) may fail if types are unrelated, for example this code won't compile (because compiler knows there is no possible conversion):
如果类型不相关,从指针(到对象)的转换可能会失败,例如此代码将无法编译(因为编译器知道不可能进行转换):
// won't compile!
string text = (string)AppDomain.Current;
Exception exception = (Exception)"abc";
This code will compile but it may fail at run-time (it depends on the effective type of casted objects) with an InvalidCastException
:
此代码将编译,但它可能会在运行时失败(这取决于强制转换对象的有效类型),并带有InvalidCastException
:
object obj = GetNextObjectFromInput();
string text = (string)obj;
obj = GetNextObjectFromInput();
Exception exception = (Exception)obj;
Conversions
转化次数
So, finally, if casts are conversion then why we need classes like Convert
are needed? Ignoring subtle differences that comes from Convert
implementation and IConvertible
implementations actually because in C# with a cast you say to the compiler:
所以,最后,如果强制转换是转换,那么为什么我们需要像Convert
are一样的类?忽略来自Convert
实现和IConvertible
实现的细微差异,实际上是因为在 C# 中,您对编译器说:
trust me, this type is that type even if you can't know it now, let me do it and you'll see.
相信我,这种类型就是那种类型,即使你现在不知道,让我做,你会看到的。
-or-
-或者-
don't worry, I don't care something will be lost in this conversion.
别担心,我不在乎这次转换会丢失什么。
For anything else a moreexplicit operation is needed (think about implications of easy casts, that's why C++ introduced long, verbose and explicit syntax for them). This may involve a complex operation (for string
-> double
conversion a parsing will be needed). Conversion to string
, for example, is always possible (via ToString()
method) but it may mean something different from what you expect so it must be more explicit than a cast (more you write, more you think about what you're doing).
对于其他任何事情,都需要更明确的操作(想想简单强制转换的含义,这就是 C++ 为它们引入冗长、冗长和明确的语法的原因)。这可能涉及复杂的操作(对于string
->double
转换需要解析)。string
例如,转换为 始终是可能的(通过ToString()
方法),但它可能意味着与您期望的不同,因此它必须比强制转换更明确(您写得越多,您就越想自己在做什么)。
This conversion can be done inside the object (using known IL instructions for that), using custom conversion operators (defined in the class to cast) or more complex mechanisms (TypeConverter
s or class methods, for example). You're not aware of what will happen to do that but you're aware it may fail (that's why IMO when a more controlledconversion is possible you should use it). In your case the conversion simply will parse the string
to produce a double
:
这种转换可以在对象内部完成(使用已知的 IL 指令),使用自定义转换运算符(在类中定义以进行转换)或更复杂的机制(TypeConverter
例如 s 或类方法)。您不知道这样做会发生什么,但您知道它可能会失败(这就是为什么 IMO 在可能进行更可控的转换时您应该使用它)。在您的情况下,转换只会解析string
生成一个double
:
double value = Double.Parse(aStringVariable);
Of course this may fail so if you do it you should always catch the exception it may throw (FormatException
). It's out of topic here but if when a TryParse
is available then you should use it (because semantically you sayit may not be a number and it's even faster...to fail).
当然这可能会失败,所以如果你这样做,你应该总是捕获它可能抛出的异常 ( FormatException
)。它在这里无关紧要,但是如果 aTryParse
可用,那么您应该使用它(因为从语义上讲,您说它可能不是数字并且它甚至更快......失败)。
Conversions in .NET can come from a lot of places, TypeConverter
, implicit/explicit casts with user defined conversion operators, implementation of IConvertible
and parsing methods (did I forget something?). Take a look on MSDN for more details about them.
.NET 中的转换可以来自很多地方、TypeConverter
隐式/显式转换以及用户定义的转换运算符、实现IConvertible
和解析方法(我忘记了什么吗?)。有关它们的更多详细信息,请查看 MSDN。
To finish this long answer just few words about user defined conversion operators. It's just sugarto let the programmer use a cast to convert one type to another. It's a method inside a class (the one that will be casted) that says "hey, if he/she wants to convert this type to that type then I can do it". For example:
要完成这个长答案,只需几句话就可以了解用户定义的转换运算符。让程序员使用强制转换将一种类型转换为另一种类型只是糖。这是一个类(将被强制转换的那个)中的一个方法,它说“嘿,如果他/她想将这种类型转换为那种类型,那么我可以做到”。例如:
float? maybe = 10; // Equals to Nullable<float> maybe = 10;
float sure1 = (float)maybe; // With cast
float sure2 = maybe.Value; // Without cast
In this case it's explicit because it may fail but this is let to the implementation (even if there are guidelines about this). Imagine you write a custom string class like this:
在这种情况下,它是明确的,因为它可能会失败,但这是让实现(即使有关于此的指导方针)。想象一下,您编写了一个这样的自定义字符串类:
EasyString text = "123"; // Implicit from string
double value = (string)text; // Explicit to double
In your implementation you may decide to "make programmer's life easier" and to expose this conversion via a cast (remember it's just a shortcut to write less). Some Language may even allow this:
在您的实现中,您可能决定“让程序员的生活更轻松”并通过强制转换公开此转换(请记住,这只是减少编写的捷径)。某些语言甚至可能允许这样做:
double value = "123";
Allowing implicit conversion to any type (check will be done at run-time). With proper options this can be done, for example, in VB.NET. It's just a different philosophy.
允许隐式转换为任何类型(检查将在运行时完成)。使用适当的选项可以做到这一点,例如,在 VB.NET 中。这只是一种不同的哲学。
What can I do with them?
我能用它们做什么?
So the final question is when you should use one or another. Let's see when you can use an explicit cast:
所以最后一个问题是你什么时候应该使用一个或另一个。让我们看看什么时候可以使用显式转换:
- Conversions between base types.
- Conversions from
object
to any other type (this may include unboxing too). - Conversions from a derived class to a base class (or to an implemented interface).
- Conversions from one type to another via custom conversion operators.
- 基本类型之间的转换。
- 从
object
到任何其他类型的转换(这也可能包括拆箱)。 - 从派生类到基类(或到已实现的接口)的转换。
- 通过自定义转换运算符从一种类型转换为另一种类型。
Only the first conversion can be done with Convert
so for the others you have no choice and you need to use an explicit cast.
只有第一次转换可以完成,Convert
所以对于其他人你别无选择,你需要使用显式转换。
Let's see now when you can use Convert
:
现在让我们看看什么时候可以使用Convert
:
- Conversions from any base type to another base type (with some limitations, see MSDN).
- Conversions from any type that implements
IConvertible
to any other (supported) type. - Conversions from/to a
byte
array to/from a string.
- 从任何基本类型到另一种基本类型的转换(有一些限制,请参阅MSDN)。
- 从实现
IConvertible
到任何其他(支持的)类型的任何类型的转换。 - 从/到
byte
数组到/从字符串的转换。
Conclusions
结论
IMO Convert
should be used each time you know a conversion may fail (because of format, because of range or because it may be unsupported), even if the same conversion can be done with a cast (unless something else is available). It makes clear to who will read your code what's your intentand that it may fail (simplifying debug).
Convert
每次您知道转换可能会失败(因为格式、范围或因为它可能不受支持)时,都应该使用IMO ,即使可以使用强制转换完成相同的转换(除非有其他可用的东西)。它明确了谁将阅读您的代码您的意图是什么,并且它可能会失败(简化调试)。
For everything else you need to use a cast, no choice, but if another better method is available then I suggest you use it. In your example a conversion from string
to double
is something that (especially if text comes from user) very often will fail so you should make it as much explicit as possible (moreover you get more control over it), for example using a TryParse
method.
对于您需要使用演员表的所有其他事情,别无选择,但如果有另一种更好的方法可用,那么我建议您使用它。在您的示例中,从string
to的转换double
(特别是如果文本来自用户)经常会失败,因此您应该使其尽可能明确(而且您可以对其进行更多控制),例如使用TryParse
方法。
Edit: what's the difference between them?
编辑:它们之间有什么区别?
According to updated question and keeping what I wrote before (about whenyou can use a cast compared to when you can/have to use Convert
) then last point to clarify is if there are difference between them (moreover Convert
uses IConvertible
and IFormattable
interfaces so it can perform operations not allowed with casts).
根据更新的问题并保留我之前写的内容(关于何时可以使用强制转换与何时可以/必须使用相比Convert
)然后最后一点要澄清的是它们之间是否存在差异(此外Convert
使用IConvertible
和IFormattable
接口,以便它可以执行操作不允许使用演员表)。
Short answer is yes, they behave differently. I see the Convert
class like a helper methods class so often it provides some benefitor slightly different behaviors. For example:
简短的回答是肯定的,它们的行为不同。我认为这个Convert
类就像一个辅助方法类,所以它经常提供一些好处或稍微不同的行为。例如:
double real = 1.6;
int castedInteger = (int)real; // 1
int convertedInteger = Convert.ToInt32(real); // 2
Pretty different, right? Cast truncates (it's what we all expect) but Convert
performs a rounding to nearest integer (and this may not be expected if you're not aware of it). Each conversion method introduces differences so a general rule can't be applied and they must be seen case by case...19 base types to convert to every other type...list can be pretty long, much better to consult MSDN case by case!
很不一样吧?强制转换会截断(这是我们都期望的),但Convert
会四舍五入到最接近的整数(如果您不知道,这可能不会发生)。每种转换方法都引入了差异,因此不能应用一般规则,必须逐个查看它们... 19 种基本类型转换为其他所有类型...列表可能很长,最好通过 MSDN 案例咨询案件!
回答by Dan
The Convert.Double
method actually just internally calls the Double.Parse(string)
method.
该Convert.Double
方法实际上只是在内部调用该Double.Parse(string)
方法。
Neither the String
type nor the Double
type define an explicit/implicit conversion between the two types, so casting will always fail.
String
类型和Double
类型都没有定义两种类型之间的显式/隐式转换,因此转换总是会失败。
The Double.Parse
method will look at each character in the string
and build a numeric value based on the values of the characters in the string
. If any of the characters are invalid, the Parse
method fails (causing the Convert.Double
method to fail as well).
该Double.Parse
方法将查看 中的每个字符string
并根据 中字符的值构建一个数值string
。如果任何字符无效,则该Parse
方法失败(Convert.Double
也会导致该方法失败)。
回答by scartag
In your example you are attempting to cast a string to a double (non integral type).
在您的示例中,您试图将字符串转换为 double(非整数类型)。
An explicit conversion is required for it to work.
它需要显式转换才能工作。
And i must point that you could have used Convert.ToDouble
instead of Convert.ToInt64
as you can lose the fractional parts of the double value when you convert to an int.
而且我必须指出,您可以使用Convert.ToDouble
而不是Convert.ToInt64
因为当您转换为 int 时,您可能会丢失双精度值的小数部分。
if your variable has the value "5.25" varDouble would have been 5.00 (loss of 0.25 because of the Conversion to Int64)
如果您的变量具有值“5.25”,则 varDouble 将是 5.00(由于转换为 Int64 而损失 0.25)
To answer your question about casting vs converting.
回答您关于转换与转换的问题。
Your cast (an explicit cast) doesn't meet the requirements for an explicit cast. the value you are trying to cast with the cast operator is invalid (i.e non integral).
您的演员表(显式演员表)不符合明确演员表的要求。您尝试使用强制转换运算符强制转换的值无效(即非整数)。
Visit this MSDN Pagefor the rules of casting / conversions
访问此MSDN 页面了解强制转换/转换规则
回答by Viktor S.
string variable = "5.00";
double varDouble = (double)variable;
Above conversion is simply not allowed by language. Here is a list of explicit casts for numerical types: http://msdn.microsoft.com/en-us/library/yht2cx7b.aspxAs you can see, even not every numerical type could be converted to another numerical type
以上转换是语言所不允许的。以下是数字类型的显式转换列表:http: //msdn.microsoft.com/en-us/library/yht2cx7b.aspx如您所见,即使不是每个数字类型都可以转换为另一种数字类型
Some more info about casting here
关于投射这里的更多信息
And how does this differ to Convert.ToDouble()?
这与 Convert.ToDouble() 有何不同?
When you cast a type, data structure is not changed. Well, in case of numerical values conversion it you may loose few bits or get few additional 0 bits. But you are still working with a number.You are just changing an amount of memory taken by that number. That is safe enough for compiler do everything needed.
当您转换类型时,数据结构不会改变。好吧,在数值转换的情况下,您可能会丢失一些位或获得一些额外的 0 位。但是你仍然在使用一个数字。您只是在更改该数字占用的内存量。这对于编译器做所有需要的事情来说已经足够安全了。
But when you are trying to cast string to a number, you can't do that because it is not enough to change amount of memory taken by variable. For instance, 5.00as a string is a sequence of "numbers":53(5) 46(.) 48(0) 48(0) - that is for ASCII, but string will contain something similar. If compiler will just take first N (4 for double? not sure) bytes from a string - that piece will contain completely different double number. At the same time Convert.ToDouble() run special algorithm which will take each symbol of a string, figure out digit which it represents and make a double number for you, if string represents a number. Languages like PHP will, roughly speaking, call Convert.ToDouble for you in background. But C#, like a statically typed language, will not do that for you. This allows you to be sure that any operation is type safe and you will not get something unexpected doing something like:
但是当你试图将字符串转换为一个数字时,你不能这样做,因为改变变量占用的内存量是不够的。例如,5.00因为字符串是“数字”序列:53(5) 46(.) 48(0) 48(0) - 这是用于 ASCII,但字符串将包含类似的内容。如果编译器只从字符串中获取前 N 个(双精度为 4 个?不确定)字节 - 该部分将包含完全不同的双精度数。同时 Convert.ToDouble() 运行特殊算法,该算法将获取字符串的每个符号,找出它代表的数字并为您制作一个双数,如果字符串代表一个数字。粗略地说,像 PHP 这样的语言会在后台为您调用 Convert.ToDouble。但是 C# 就像静态类型语言一样,不会为您做到这一点。这使您可以确保任何操作都是类型安全的,并且您不会在执行以下操作时遇到意外情况:
double d = (double)"zzzz"
回答by Keen
Casting a string to a double like that is not allowed C# which is why you get an Exception, you need to have the string converted (MSDN docthat shows acceptable conversion paths). This is simply because a string isn't necessarily going to contain numeric data, but the various numeric types will (barring null values). A Convert
will run a method that will check the string to see if it can be turned into a numeric value. If it can, then it will return that value. If it can't, it'll throw an exception.
C# 不允许将字符串转换为 double 类型,这就是为什么会出现异常,您需要转换字符串(显示可接受的转换路径的MSDN 文档)。这仅仅是因为字符串不一定包含数字数据,但各种数字类型会(空值除外)。AConvert
将运行一个方法来检查字符串以查看它是否可以转换为数值。如果可以,那么它将返回该值。如果不能,它会抛出异常。
To convert it, you have several options. You used the Convert
method in your question, there's Parse
which is largely similar to Convert
, but you should also look at TryParsewhich would allow you to do:
要转换它,您有多种选择。您Convert
在问题中使用了该方法,该方法与Parse
基本相似Convert
,但您还应该查看TryParse,它可以让您执行以下操作:
string variable = "5.00";
double varDouble;
if (Double.TryParse(variable, out varDouble)) {
//Code that runs if the conversion succeeded.
} else {
//Code that runs if the conversion failed.
}
This avoids the possible exception should you try to Convert
or Parse
a non-numerical string.
这样就避免了可能的例外是你应该尝试Convert
或者Parse
非数字的字符串。
回答by Olivier Jacot-Descombes
Casting does not involve any conversion, i.e. the internal representation of a value is not changed. Example:
转换不涉及任何转换,即值的内部表示不会改变。例子:
object o = "Hello"; // o is typed as object and contains a string.
string s = (string)o; // This works only if o really contains a string or null.
You can convert a double
to string
like this
您可以将 a 转换double
为string
这样
double d = 5;
string s = d.ToString(); // -> "5"
// Or by specifying a format
string formatted = d.ToString("N2"); // -> "5.00"
You can convert a string
to a double
in several ways (here just two of them):
您可以通过多种方式将 a 转换string
为 a double
(这里只有其中两种):
string s = "5";
double d = Double.Parse(s); // Throws an exception if s does not contain a valid number
Or the safe way
或者安全的方式
string s = "5";
double d;
if (Double.TryParse(s, out d)) {
Console.WriteLine("OK. Result = {0}", d);
} else {
Console.WriteLine("oops!");
}
回答by Servy
Casting is a way of telling the compiler, "I know that you think that this variable is a Bar, but I happen to know more than you; the object is actually a Foo, so let me treat it as if it were a Foo from now on." Then, at runtime, if the actual object turned out to really be a Foo then your code works, if it turns out that the object was not a Foo at all, then you get an exception. (Specifically an System.InvalidCastException
.)
强制转换是一种告诉编译器的方式,“我知道你认为这个变量是一个 Bar,但我碰巧比你知道的更多;这个对象实际上是一个 Foo,所以让我把它当作一个来自从今起。” 然后,在运行时,如果实际对象确实是 Foo,那么您的代码可以工作,如果结果表明该对象根本不是 Foo,则您会收到异常。(特别是System.InvalidCastException
.)
Converting on the other hand is a way of saying, "If you give me an object of type Bar I can create a brand new Foo object that represents what is in that Bar object. I won't change the original object, it won't treat the original object differently, it will create something new that is just based on some other value. As to how it will do that, it could be anything. In the case of Convert.ToDouble
it will end up calling Double.Parse
which has all sorts of complex logic for determining what types of strings represent what numeric values. You could write your own conversion method that mapped strings to doubles differently (perhaps to support some entirely different convention for displaying numbers, such as roman numerals or whatever). A conversion could do anything, but the idea is that you're not really asking the compiler to do anything for you; you are the one writing the code to determine how to create the new object because the compiler, without your help, has no way of knowing how to map (as an example) a string
to a double
.
另一方面,转换是一种说法,“如果你给我一个 Bar 类型的对象,我可以创建一个全新的 Foo 对象来表示那个 Bar 对象中的内容。我不会改变原始对象,它不会” t 以不同的方式对待原始对象,它将创建一些仅基于其他值的新对象。至于它将如何做到这一点,它可以是任何东西。在这种情况下,Convert.ToDouble
它最终会调用Double.Parse
它有各种复杂的逻辑来确定什么类型的字符串代表什么数值。您可以编写自己的转换方法,以不同的方式将字符串映射到双精度(也许支持一些完全不同的数字显示约定,例如罗马数字或其他)。转换可以做任何事情,但这个想法是你并不是真的要求编译器为你做任何事情;您是编写代码以确定如何创建新对象的人,因为如果没有您的帮助,编译器无法知道如何将 a 映射(作为示例)string
到 a double
。
So, when do you convert, and when do you cast? In both cases we have some variable of a type, let's say A, and we want to have a variable of type B. If our A object really, actually, under the hood, is a B, then we cast. If it's not really a B, then we need to Convert it, and define how the program is supposed to get a B from an A.
那么,你什么时候转换,什么时候投射?在这两种情况下,我们都有一个类型的变量,假设是 A,并且我们想要一个类型为 B 的变量。如果我们的 A 对象实际上,实际上,在幕后,是一个 B,那么我们就进行强制转换。如果它不是真正的 B,那么我们需要转换它,并定义程序应该如何从 A 获取 B。
回答by Scott Hannen
double varDouble = (double)variable
assumes that variable
is already a double. If variable
isn't a double (it's a string) then this will fail.
double varDouble = Convert.ToDouble(variable)
does like it says - it converts.If it can parse or otherwise extract a double from variable
then it will.
double varDouble = (double)variable
假设那variable
已经是双倍了。如果variable
不是双精度(它是一个字符串),那么这将失败。
double varDouble = Convert.ToDouble(variable)
确实像它说的那样 - 它会转换。如果它可以解析或以其他方式从中提取双精度值,variable
那么它就会。
I second using Double.Parse
or Double.TryParse
because it more clearly indicates what's supposed to be happening. You're starting with a string and expecting it to be convertible to a double. If there's any doubt, use TryParse
.
我第二次使用Double.Parse
orDouble.TryParse
因为它更清楚地表明应该发生什么。您从一个字符串开始并期望它可以转换为双精度。如果有任何疑问,请使用TryParse
.
If variable
is a method argument, change the type to double. Make the caller responsible for providing the correct type. That way the compiler does the work for you.
如果variable
是方法参数,则将类型更改为双精度。让调用者负责提供正确的类型。这样编译器就会为您完成工作。
回答by Salah Akbari
From MSDN
:
来自MSDN
:
Explicit conversions (casts): Explicit conversions require a cast operator. Casting is required wheninformation might be lost in the conversion, or when the conversion might not succeed for other reasons. Typical examples include numeric conversion to a type that has less precision or a smaller range, and conversion of a base-class instance to a derived class.
显式转换(强制转换):显式转换需要强制转换运算符。铸造需要时可能会在转换过程中丢失的信息,或当转换可能不会因其他原因取得成功。典型示例包括将数值转换为精度较低或范围较小的类型,以及将基类实例转换为派生类。
Consider the following example:
考虑以下示例:
double a = 2548.3;
int b;
b = (int)a; //2548 --> information (.3) lost in the conversion
And also:
并且:
A cast is a way of explicitly informing the compiler that you intend to make the conversion and that you are aware that data loss might occur.
强制转换是一种明确通知编译器您打算进行转换并且您知道可能会发生数据丢失的方式。
You could use System.Convert
class when you want to convert between non-compatibletypes. The main differencebetween castingand convertis compileand run-time. The type conversion exceptions are appeared at run-time, i.e a type cast that fails at run-time will cause an InvalidCastException
to be thrown.
System.Convert
当您想在不兼容的类型之间进行转换时,您可以使用class 。cast和convert之间的主要区别是compile和run-time。类型转换异常出现在运行时,即在运行时失败的类型转换将导致 an被抛出。
InvalidCastException
Conclusion:结论:在强制转换中,您告诉编译器
a
a
是真正的类型b
b
,如果是这样,则项目构建时不会出现任何错误,如下例所示:double s = 2;
int a = (int) s;
But in conversion you're saying to the compiler there is a way to create a new object from a
of type b
, please do it and project builds without any errors but as I said if type cast fails at run-time, it will cause an InvalidCastException
to be thrown.
但在转换你说的编译器有是创建一个新的对象的方式a
类型b
,请做到这一点,项目建立没有任何错误,但正如我所说,如果类型转换在运行时出现故障,它会导致InvalidCastException
对被抛出。
For example the code below is never compile because compiler detect that cannot cast expression of type DateTime
to type int
:
例如,下面的代码永远不会编译,因为编译器检测到无法将 type 的表达式转换DateTime
为 type int
:
DateTime s = DateTime.Now;
int a = (int)(s);
But this one is compiled successfully:
但是这个编译成功了:
DateTime s = DateTime.Now;
int a = Convert.ToInt32(s);
But at run-time you will get InvalidCastException
which says:
但是在运行时你会得到InvalidCastException
它说:
Invalid cast from 'DateTime' to 'Int32'.
从“DateTime”到“Int32”的无效转换。
回答by TomHardy
The most important difference is that if type castingis used and the conversion fails (say we are converting a very big float value to int ) no exception will be thrown and the minimum value an int can hold will be shown. But in case of using Convert, an exception will be thrown for such scenarios.
最重要的区别是,如果使用类型转换并且转换失败(假设我们将一个非常大的浮点值转换为 int ),则不会抛出异常,并且将显示 int 可以容纳的最小值。但是在使用Convert 的情况下,此类场景将引发异常。