在杰西自由的学习C#的书,他说,“一个类型的对象可以被转换成另一种类型的对象。这就是所谓的铸造。”
如果调查从下面的代码产生的白细胞介素,你可以清楚地看到,铸造分配没有做同样的事情,转换后的分配。 在前者中,你可以看到发生的装箱/拆箱; 在后者,你可以看到一个转换方法的调用。
我知道它到底可能只是一个愚蠢的语义差异 - 但铸造只是一个字的转换。 我的意思并不是要表露无疑,但我不感兴趣,在这个人的直觉 - 观点并不指望在这里! 任何人都可以指向确认或者否认铸造和加工是一回事一个明确的参考?
object x;
int y;
x = 4;
y = ( int )x;
y = Convert.ToInt32( x );
谢谢
RP
注意马特的约显性/隐性后评论说:
我不认为隐性/明确的区别。 在我发布的代码,这种变化是在两种情况下的明确。 隐式转换是当你分配一个短为int发生什么。
注意Sklivvz:
我想确认我的杰西自由的(否则通常是清晰和明确的)语言松动的怀疑是正确的。 我认为杰西自由当时正在用他的语言有点松。 据我所知,铸造在对象层次路由 - 也就是说,你不能从一个整数转换为一个字符串,但你可以从从System.Exception派生于System.Exception的自定义异常施放。
有意思的是,虽然,当你试图从一个int转换为字符串,编译器会告诉你,它不能“转化”的值。 也许杰西是更正确的比我想象的!
Answer 1:
简单的答案是:这取决于。
对于值类型,铸造将涉及到它真正转换为不同的类型。 例如:
float f = 1.5f;
int i = (int) f; // Conversion
当铸造表达unboxes,结果(假设它的工作原理) 通常只是一个什么盒子,与同类型的副本。 当然也有例外,但是 - 你可以从一个装箱的int拆箱到一个枚举(与下面的int型),反之亦然; 同样可以从一个装箱的int到可空<int>的拆箱。
当铸件的表达是一个引用类型到另一个没有用户定义的转换涉及,也没有转换至于对象本身而言-只是参考 “变化”的类型-这是真的只有这样了值被认为,而不是参考本身(这将是相同的比特作为前)。 例如:
object o = "hello";
string x = (string) o; // No data is "converted"; x and o refer to the same object
当用户定义的转换动手,这通常需要返回一个不同的对象/值。 例如,你可以定义转换为字符串为自己的类型 - 这肯定不会是相同的数据作为自己的目标。 (这可能是从你的对象称为不已,当然现有字符串)。在我的经验,用户定义的转换通常是值类型而不是引用类型之间存在的,所以这是很少的问题。
所有这些计数为转换在规范方面的-但他们不计一切作为对象转换成不同类型的对象 。 我怀疑这是杰西自由是与术语宽松的情况下 - 我注意到,在编程C#3.0,这是我刚读了。
这是否面面俱到?
Answer 2:
绝对不!
转换尝试通过“任何可能的手段”让你一个Int32。 演员做这样的事。 随着投你告诉编译器把对象作为诠释,无需转换。
你应该总是使用铸铁,当你知道(设计),对象是一个Int32,或者有一个转换操作符来的Int32(如浮动,例如)其他类。
转换应与字符串中使用,或与其他类。
试试这个
static void Main(string[] args)
{
long l = long.MaxValue;
Console.WriteLine(l);
byte b = (byte) l;
Console.WriteLine(b);
b = Convert.ToByte(l);
Console.WriteLine(b);
}
结果:
9223372036854775807
255
未处理的异常:
System.OverflowException:值大于Byte.MaxValue或小于Byte.MinValue在System.Convert.ToByte(Int64的值)[0x00000]在Test.Main(System.String []参数)[0x00019]在/ home /马/develop/test/Exceptions.cs:15
Answer 3:
我见过可以看到下面最好的解释,随后链接到源:
” ......事实是比这更复杂一点。.NET提供了从点A到B点,因为它是三种方法。
首先,有隐式转换。 这是一个不需要你做任何事情比分配更多的演员:
int i = 5;
double d = i;
这些也被称为“扩大转换”和.NET让您无需任何转换运算符执行它们,因为你永远不能丢失任何信息,这样做:双的有效值的可能范围包括有效值范围为int,然后一些,所以你永远不会做这个任务,然后发现你惊恐地发现运行时下降了几个数字了你的int值。 对于引用类型,隐式转换背后的规则是,中投可能不会抛出一个InvalidCastException:很显然编译器,中投一直有效。
你可以做出新的隐式转换运营商自己的类型(这意味着你就可以说打破了所有的规则,如果你比别人笨它隐式转换)。 拇指的基本规则是隐式转换不能包括在过渡丢失信息的可能性。
另外,底层的表示并在此转换改变:双重从一个int完全不同表示。
第二种转换是显式的转换。 只要有信息丢失的可能性,或有可能,中投可能是无效的,因此抛出一个InvalidCastException显式的转换是必需的:
double d = 1.5;
int i = (int)d;
在这里,你显然会失去信息:我将是1投后,使0.5丢失。 这也被称为“收缩”转换,而编译器要求你有一个明确的CAST(INT),以表明是的,你知道信息可能会丢失,但你不在乎。
同样,引用类型,编译器需要的情况下进行显式转换中投可能不是在运行时有效,因为是的,你知道有一种风险,即一个信号,但你知道你在做什么。
第三类转换是一个涉及表示这样的彻底改变了设计师没有提供更明确的转换:他们让你调用一个方法,以进行转换:
string s = "15";
int i = Convert.ToInt32(s);
请注意,没有什么东西是绝对需要一个方法调用在这里。 隐式和显式转换的方法调用过(这就是你如何使自己的)。 设计师可以很容易地创建一个显式类型转换操作符转换字符串为int。 你调用一个方法的要求是一个风格上的选择,而不是语言的一个基本要求。
文体推理是这样的:字符串到int是一个复杂的转换,有很多事情要去可怕的错误的机会:
string s = "The quick brown fox";
int i = Convert.ToInt32(s);
因此,该方法调用为您提供了文档阅读,以及广泛的暗示,这东西不仅仅是一个快速投更多。
在设计自己的类型(特别是你自己的值类型),你可能会决定创建的类型转换操作和转换功能。 将“隐式转换”,“显式转换”和“转换功能”领土的线是一个有点模糊,所以不同的人可能会做出不同的决定为应该是什么。 只要设法记住信息丢失,和潜在的异常和无效数据,并应帮助你决定。”
http://bytes.com/forum/post1068532-4.html
Answer 4:
铸造涉及引用
List<int> myList = new List<int>();
//up-cast
IEnumerable<int> myEnumerable = (IEnumerable<int>) myList;
//down-cast
List<int> myOtherList = (List<int>) myEnumerable;
注意,针对myList中的操作,诸如添加的元素,反映在myEnumerable和myOtherList。 这是因为他们(不同类型的)所有引用同一个实例。
截至铸造是安全的。 如果程序员已在类型错误下铸造可以产生运行时错误。 安全下铸造超出这个答案的范围。
转换包括实例
List<int> myList = new List<int>();
int[] myArray = myList.ToArray();
myList中被用于产生myArray的。 这是一种非破坏性的转换(myList中工作完全正常此操作后)。 还要注意,对myList中的操作,诸如添加的元素,不会反映在myArray的。 这是因为他们是完全独立的实例。
decimal w = 1.1m;
int x = (int)w;
有使用C#的转换语法是操作实际上是转换 。
Answer 5:
语义之外,快速测试显示它们是不等价的!
他们做任务不同(或者,他们做不同的任务)。
x=-2.5 (int)x=-2 Convert.ToInt32(x)=-2
x=-1.5 (int)x=-1 Convert.ToInt32(x)=-2
x=-0.5 (int)x= 0 Convert.ToInt32(x)= 0
x= 0.5 (int)x= 0 Convert.ToInt32(x)= 0
x= 1.5 (int)x= 1 Convert.ToInt32(x)= 2
x= 2.5 (int)x= 2 Convert.ToInt32(x)= 2
注意x=-1.5
和x=1.5
的情况。
Answer 6:
的流延是告诉编译器/ interperter,事实上,对象是该类型的(或具有该类型的基本类型/接口)。 这是相比于转换做它不再是编译器/ interperter做的工作,但功能actualling解析字符串,做数学转换为数字的一个相当快的事情。
Answer 7:
总是铸造装置改变对象的数据类型。 这可以例如通过将一个浮点值,为整数值,或通过重新解释的位来完成。 这是usally语言支持(读:编译器支持)操作。
术语“转换”有时用于铸造,但它通常是由一些库或你自己的代码实现,并不一定导致相同的铸造。 举例来说,如果你有一个帝国的权重值,并将其转换为公制重量,它可能停留在相同的数据类型(比如浮动),但成为一个异数。 另一个典型的例子是从度转换为弧度。
Answer 8:
在讲话的语言- /框架不可知方式,从一种类型或类别转换为另一种被称为流延 。 这是.NET也是如此,作为第一个四行显示:
object x;
int y;
x = 4;
y = ( int )x;
C和C类语言(如C#)使用(newtype)somevar
语法铸造。 在VB.NET中,例如,有这个明确的内置功能。 最后一行将被写成:
y = CInt(x)
或者,对于更复杂的类型:
y = CType(x, newtype)
其中“C”显然是短期的“投”。
.NET也有Convert()
函数,但是。 这不是一个内置的语言功能(不同于以上两种),而是框架之一。 当您使用不一定与.NET一起使用的语言这变得更加清晰:他们仍然很可能有自己铸造的方法,但它是.NET,增加Convert()
。
马特说,在行为上的区别是Convert()
为更加明确。 而不是仅仅告诉编译器把y
作为整数等效的x
,则是专门告诉它改变x
以这样的方式适合于整数类, 然后将结果分配给y
。
你的具体情况,铸造做了什么叫做“开箱”,而Convert()
实际上将获得整数值。 结果就会出现相同的,但也有更好的细微差别由Keith解释 。
Answer 9:
根据表1-7中MCTS自控进度培训工具包(考试70-536)的第1章,第4课题为“为显式转换方法”第55页:微软的.NET Framework 2.0应用程序开发基础 ,肯定是有它们之间的区别。
System.Convert是独立于语言和转换“实现了System.IConvertible接口类型之间。”
(类型)转换运算符是C#语言特异性特征,其将“定义的转换运算符的类型之间”。
此外,实现自定义转换时, 建议它们之间的不同 。
每题为如何实施转化的自定义类型的第56-57页中上面提到的教训, 转换操作符(铸造)是指用于简化数字类型之间的转换,而转换的部分()使特定文化的转换 。
哪种技术取决于您选择要执行的转换的类型:
它应该是清晰的,现在既然投转换操作符从IConvertible接口单独实现,即转换()不是铸造不一定仅仅是另一个名字。 (但是我可以设想其中一个实施方式中可以指的是其他以确保一致性)。
Answer 10:
不要忘了铸造和转换变量的其他方法:如,解析的TryParse以及兼容的数据类型之间的隐式转换。
这个网站有一个很好的样本什么的大多数方法的输出: C#装箱和拆箱
所以考虑到这些样品的差异:
int i = 3, x;
long l;
string s = "5";
基本上,你可以有隐式转换,两个兼容类型之间:
l = i;
显式转换使用拆箱或作为关键字:
s = (string)i;
//or
s = i as string;
利用System.Convert方法显式转换:
i = System.Convert.ToInt32(s);
使用从所定义的数据类型的方法的显式转换:
i = int.Parse(s);
i = int.TryParse(s, x);
使用从可变的实例方法的显式转换:
s = i.ToString();
我想, 铸造是简单地使两个兼容类型之间分配的方式。
转换是,如果你需要明确一个值从一个不兼容的类型复制到另一个,你可以不相信邪恶胁迫 。
一些好的信息也MSDN: 铸造和类型转换
Answer 11:
铸造基本上只是告诉运行时“假装”的对象是新类型。 它实际上并没有转换或改变对象以任何方式。
转换,但是,将执行操作,把一个类型到另一个。
举个例子:
char caster = '5';
Console.WriteLine((int)caster);
这些语句的输出将是53,因为所有的运行时所做的是看位模式,并把它作为一个int。 你最终得到什么字符5的ASCII值,而不是数字5。
如果你使用Convert.ToInt32(施法者),但是,你会得到5,因为它实际上读取字符串和正确地修改它。 (本质上,它知道,ASCII值53是真正的整数值5)
Answer 12:
所不同的有转换是否是隐性或显性的。 第一个在那里是一个演员,第二个是,其转换功能更加显式调用。 他们可能去用不同的方式做同样的事情。
文章来源: Is casting the same thing as converting?