在杰西身自由的学习C#书,他说"对象的一个类型的可转化为对象的另一个类型。这就是所谓铸造"。

如果你调查IL产生的代码下面,你可以清楚地看到,铸造的分配是不是做同样的事情转换的分配。在前者中,你可以看到拳/拆箱发生;在后一种你可以看到一个电话,一个转换的方法。

我知道最终这可能只是一个愚蠢的语义区别-但是铸造只是另一个词转换。我不想表露无疑,但我不感兴趣,任何人的感觉,在这...见不计在这里!任何人都可以点一个明确的参考,确认或否认,如果铸造和转换都是同样的事情吗?

    object x;
    int y;

    x = 4;

    y = ( int )x;

    y = Convert.ToInt32( x );

谢谢你

rp

注意增加之后,马特的评论显性/隐:

我不认为隐含/明确的区别。在代码我贴,改变是明确在这两种情况。一个隐含的转换是什么时发生分配一个简短到一个int.

注意到Sklivvz:

我想确认,我怀疑的松动的杰西自由(否则通常清晰和明确的)语言是正确的。我认为杰西的自由是正在被一点点宽松与他的语言。我的理解是,铸路由在目层次的--即,你不能从整数字符串但是你可以从定义的例外,来自系统。例外的系统。例外。

这很有趣,不过,这当你试图从一个int到一串编译器告诉你,这不可能"转换"的价值。也许杰西是更多的正确比我的思想!

有帮助吗?

解决方案

简单的答案是:它取决于。

对于值类型,转换将涉及真正将其转换为其他类型。例如:

float f = 1.5f;
int i = (int) f; // Conversion

当转换表达式取消装箱时,结果(假设它有效)通常只是框中内容的副本,具有相同的类型。但是有一些例外 - 你可以从盒装的int到enum(底层类型为int)取消装箱,反之亦然;同样,你可以从盒装int中取消装箱到Nullable <!> lt; int <!> gt;。

当转换表达式从一种引用类型转换为另一种引用类型并且不涉及用户定义的转换时,就对象本身而言,没有转换 - 只有引用的类型 <! > QUOT;!变化<> QUOT; - 这实际上只是值的方式,而不是引用本身(它将与以前相同)。例如:

object o = "hello";
string x = (string) o; // No data is "converted"; x and o refer to the same object

当涉及用户定义的转换时,此通常需要返回不同的对象/值。例如,您可以为自己的类型定义转换为字符串 - 和  这肯定与您自己的对象不一样。 (当然,它可能是从您的对象引用的现有字符串。)根据我的经验,用户定义的转换通常存在于值类型而不是引用类型之间,因此这很少成为问题。

所有这些都被视为规范方面的转换 - 但它们并不都算作将对象转换为其他类型的对象。我怀疑这是一个Jesse Liberty的术语松散的例子 - 我注意到在C#3.0编程中,我刚读过这个。

这涵盖了一切吗?

其他提示

绝对不是!

转换尝试通过<!>引用Int32到达任何可能的方式<!>“; Cast没有做那种事。使用强制转换,您告诉编译器将对象视为Int,而不进行转换。

当您(通过设计)知道对象是Int32或其他具有Int32的转换运算符的类(例如float)时,应始终使用强制转换。

Convert应与String或其他类一起使用。

试试这个

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 [] args)[0x00019] in   /home/marco/develop/test/Exceptions.cs:15

最好的解释,我看到下面可以看到,随后通过的链接资料来源:

"...真相是一个比较复杂。.网提供 三种方法获得从A点到B点,因为它是。

第一,有隐含的演员。这是演员,不 要求你做任何事情比分配:

int i = 5;
double d = i;

这些也被称为"扩大转换"。净允许你 执行他们没有任何投操作因为你可能永远不会失去任何 信息这样做:可能的范围的有效值的一双 涵盖的范围的有效值int然后一些,所以 你永远不会做这种分配,然后发现你的 恐怖运行时放弃了几个数字掉你的int值。对于 参照类型的规则背后的一个隐含的浇铸 可能永远不会扔InvalidCastException:清楚的是要编译器 铸总是有效的。

你可以使新的隐铸经营者为自己的类型(其中 意味着你可以做的隐性转换,打破所有的规则,如果 你是愚蠢的大约)。基本规则是,一个隐含的 铸可以从不包括可能失去的信息 过渡。

注意,潜在的表示 有没有 改变在这 转换:一个双人表示完全不同的一个int.

第二种类的转换,是一个明确的演员。一个明确的铸是 所需的只要有可能失去信息,或 还有一种可能性,铸可能不是有效的,并因此扔 InvalidCastException:

double d = 1.5;
int i = (int)d;

在这里,你都明显地会失去信息:我将是1后 铸造的,因此0.5丢失。这也被称为"狭窄" 转换,以及编译器需要包括一个明确的铸造 (int),以表明,是的,你知道这些信息可能丢失了,但是 你不关心。

同样,参照类型的编译器,需要明确转换中 在哪些情况下铸可能不会有效运行时,作为一个信号 那是,你知道有风险,但是你知道你在做什么。

第三种类的转换,是一种涉及这样一个根本性的改变 在代表性的设计师没有提供更明确 演员:他们让你呼叫一个方法中,为了做转换:

string s = "15";
int i = Convert.ToInt32(s);

注意,没有什么,绝对需要的方法。隐含和明确的转换方法的呼吁过(这就是你怎么做 你自己的)。设计者可以很容易地创造了一个明确的 投员转化成一串一个int.要求 你呼叫一个方法是一个风格的选择,而不是一个根本性 要求的语言。

该文体的推理是这样的:串到int是 复杂的转化有很多机会的事情 可怕的错误:

string s = "The quick brown fox";
int i = Convert.ToInt32(s);

作为这种方法,该方法通话给你的文件阅读,一流的 暗示,这是更多的东西不仅仅是一个快速演员。

当设计自己的种类(特别是你自己的价值类型),您 可能决定创建的铸运营商和转换功能。线 除"隐铸","明确的铸造",并"转换功能的" 领土是有点模糊,因此不同的人可能会做出不同的 决定什么应该是什么。只要试着去记住 信息损失,以及潜在的例外和无效的数据,以及 应该帮助你决定。"

  • 布鲁木月16日2005年

http://bytes.com/forum/post1068532-4.html

投射涉及参考

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#中使用强制语法的操作是

除了语义,快速测试表明它们不等同!
他们以不同的方式完成任务(或者,他们执行不同的任务)。

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.5x=1.5案例。

强制转换告诉编译器/交互操作者该对象实际上属于该类型(或者具有该类型的基本类型/接口)。与转换相比,这是一个非常快速的事情,它不再是编译器/交互操作员,而是一个实现解析字符串并进行数学转换为数字的函数。

转换始终意味着更改对象的数据类型。这可以通过例如将浮点值转换为整数值或通过重新解释位来完成。它通常是语言支持的(读取:编译器支持的)操作。

术语<!>“;转换<!>”;有时用于转换,但它通常由某些库或您自己的代码完成,并不一定与转换相同。例如,如果您具有英制权重值并将其转换为公制权重,则它可能保持相同的数据类型(例如,浮点数),但会变为不同的数字。另一个典型的例子是从度数转换为弧度。

根据表1-7的标题为"方法对于明确的转变",在第55页,在第1章,第4课的 MCT自学培训工具包(考试70-536):微软®。Framework2.0的应用程序开发基金会, 但肯定有区别。

系统。转换 是的语言无关,并将转换"之间的类型,实现 系统。请参口."

(类型)投操作员 是一个 C#特 语言功能转换"类型之间的定义 转换经营者."

此外,在实现自定义的转换, 咨询意见的不同之处 他们之间。

每一节 如何实现转换中的定义类型 在pp.第56至57在课程中引述, 转换运营商(铸造)是为了简化之间的转换数字类型,而将其转换()使特定文化转换.

这种技术选择取决于这种类型的转换你想要的执行:

  • 定义 转换经营者 为了简化缩小和扩大 转换之间的数字类型。

  • 实施 系统。请参 为使转换过 系统。转换。使用这种技术的启用文化特定的转换。

  • ...

应该更加清晰现在,由于投转换操作者实施单独的请参接口,这一转换()不一定仅仅是另一个名称铸造。(但是我可以想象,其中一个实施可参考其他以确保一致性).

不要忘记转换和转换变量的其他方法:as,Parse,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上的一些好消息:投射和类型转换

Casting实质上只是告诉运行时<!>“;假装<!>”;对象是新类型。它实际上不会以任何方式转换或更改对象。

然而,

转换将执行将一种类型转换为另一种类型的操作。

举个例子:

char caster = '5';
Console.WriteLine((int)caster);

这些语句的输出将是53,因为所有运行时都会查看位模式并将其视为int。你最终得到的是字符5的ascii值,而不是数字5。

但是,如果你使用Convert.ToInt32(caster),你会得到5,因为它实际上是读取字符串并正确修改它。 (基本上它知道ASCII值53实际上是整数值5.)

不同之处在于转换是隐式转换还是显式转换。第一个是强制转换,第二个是对转换函数的更明确的调用。他们可能会以不同的方式做同样的事情。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top