在值tye数组上使用as运算符 [英] Using as operator on value tye array

查看:63
本文介绍了在值tye数组上使用as运算符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

亲爱的所有

我在值类型数组上使用as运算符时遇到一个小问题。


这是我要做的一个例子。


使用System;


使用System.Collections.Generic;


使用System.Text ;


名称空间TestDynamicCast


{


班级计划


{


static void Main(string [] args)


{


uint [] array1 = {uint.MaxValue - 1,uint.MaxValue - 2};


MyMethod(array1);


}


public static void MyMethod(Array arr)


{


int [] afterCast1 = arr as int [];


if(null!= afterCast1)// cast成功。这是正确的吗?


{


// DoSomeThing


}
< br $> b $ b其他


{


float [] afterCast2 = arr as float [];


if(null!= afterCast2)//强制转换失败哪个没问题


{


// DoSomeThingElse


}


}


}


}


}


我认为首先''if''条件本身必须失败,因为int []和uint []是

不一样,但是它能够成功投射它。


请让我知道我的代码出了什么问题以及如何解决这个问题
问题

提前致谢。


__________________________________________________ ___________________________

Krishna Rao K

Lucid Software Ltd 104,NSIC STP Complex | Guindy工业区|

Ekkattuthangal | Chennai 600032''+ 91 44 2225 2273/76,+ 91 98407 28998

__________________________________________________ ______

解决方案

在星期二, 2008年6月10日22:55:10 -0700,Jon Skeet [C#MVP]< sk *** @ pobox.com>

写道:


[...]


>请让我知道我的代码出了什么问题以及如何解决这个问题



基本上C#本身并不相信转换是有效的,但是

CLR很乐意这样做。



我很高兴你已经解释过了(不过简单:))。我只是花了一大笔时间来试图整合C#

规范的所有不同部分,这似乎解决了这个问题,而我所能想到的只是它不会起作用。


我很好奇:CLR允许覆盖C#
$ b的规则是什么$ b规格?或者,换句话说,鉴于CLR本身没有检查这个b $ b,为什么C#编译器没有发出适当的代码来处理

情况?


如果C#规范刚刚将其作为一般语言语义问题,我可能会看到当前的行为。但该规范明确指出:


对于在运行时成功的显式引用转换,

源操作数的值必须为null,或者_actual_

源操作数引用的对象类型必须是

a类型,可以通过

隐式引用转换转换为目标类型。


在这种情况下,没有隐式引用转换可以将实际类型(uint [])转换为目标类型(int [] )。如果C#规范

正在发表关于_run-time_行为的陈述,那么在我看来,当运行时不能保证行为时,编译器是b / b
需要

to。


我意识到这是一个深奥的问题,但我想知道你是否b
关于这是否真的被认为是一个错误的任何见解

重要的人(相对于我或OP ...我知道_I_认为它是一个

bug),或者这是C#编译器所声称的是什么?b
按预期工作?


Pete


6月11日上午7:19,Peter Duniho < NpOeStPe ... @nnowslpianmk.com>

写道:


基本上C#本身没有'不相信转换是有效的,但是

CLR很乐意这样做。



我很高兴你已经解释过了(但是很简单:))。我只是花了一大笔时间来试图整合C#

规范的所有不同部分,这似乎解决了这个问题,而我所能想到的只是这不是
应该不行。



事实上,如果你试图直接从int []转到uint [] -

编译器赢了不要让你。你必须通过数组,对象或

之类的东西。


我很好奇:CLR的规则是什么允许覆盖C#

规范?或者,换句话说,鉴于CLR本身没有检查这个b $ b,为什么C#编译器没有发出适当的代码来处理

情况?



简而言之,C#和CLR规范在

转换的各个方面都没有完全一致。这当然是不幸的,但在某些时候很可能是

的情况。


如果C#规范刚刚将其保留为一般语言语义问题,我可能会看到当前的行为。但该规范明确指出:


对于在运行时成功的显式引用转换,

源操作数的值必须为null,或者_actual_

源操作数引用的对象类型必须是

a类型,可以通过

隐式引用转换转换为目标类型。


在这种情况下,没有隐式引用转换可以将实际类型(uint [])转换为目标类型(int [] )。如果C#规范

正在发表关于_run-time_行为的陈述,那么在我看来,当运行时不能保证行为时,编译器是b / b
需要

到。



对。我认为在这种情况下,规范应该明确地指出

运行时可以自由地使更多的东西有效。否则它是* b $ b *非常*规定运行时。


我意识到这是一个深奥的问题,但我我想知道你是否b / b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b我知道_I_认为它是一个/ b
bug,或者这是C#编译器所声称的是什么?b $ b按预期工作?



我还没有真正检查过CLI规范,但我肯定会想象它会被允许在那里。我怀疑它会被视为按预期工作,

但不幸的是在规范中误导。我会用C#

团队提高它,看看他们说了什么。我个人希望它能保持原样

是 - 如果编译器在每次转换时都会产生额外的检查,那么这将是非常缓慢的,只是为了让事情失败。

偶尔的情况。我更希望规范有一个警告

转换保证在情况X中成功,但*可能*也*

在其他情况下成功。 br />

Jon


嗨KK,


我相信你正在运行代码在未选中的模式中否则

语句


uint [] array = {uint.MinValue - 1,uint.MaxValue - 2};


会给你一些编译错误。


然而,这不是你面临的问题的原因。
有这个代码执行的两个转换操作。当uint []传递给Array的方法时,第一次施法是完成的。
。第二次转换为

数组到int [],两者都完全有效,代码也是如此。


如果你想让第一个条件失败,试试通过单位[]

作为uint []本身。


public static void MyMethod(unit [] arr)

{

int [] afterCast1 = arr as

int []; //这是一个错误。

if(null!= afterCast1)// cast成功。这是正确的吗?

{

// DoSomeThing

}

}


现在您将遇到错误。


我希望这对您有所帮助!!!


-Cnu

Dear All
I have a small problem with using as operator on value type array.

Here is an example what I am trying to do.

using System;

using System.Collections.Generic;

using System.Text;

namespace TestDynamicCast

{

class Program

{

static void Main(string[] args)

{

uint[] array1 = { uint.MaxValue - 1, uint.MaxValue - 2 };

MyMethod(array1);

}

public static void MyMethod(Array arr)

{

int[] afterCast1 = arr as int[];

if (null != afterCast1) //cast is successfull. Is it correct?

{

//DoSomeThing

}

else

{

float[] afterCast2 = arr as float[];

if (null != afterCast2) //cast fails which is OK

{

//DoSomeThingElse

}

}

}

}

}

I think first ''if'' condition itself must fail because int[] and uint[] are
not same, but it''s able cast it successfully.

Please let me know what''s going wrong with my code and how to solve this
problem
Thanks in advance.

__________________________________________________ ___________________________
Krishna Rao K
Lucid Software Ltd 104, NSIC STP Complex | Guindy Industrial Estate |
Ekkattuthangal | Chennai 600032 '' +91 44 2225 2273 / 76 , +91 98407 28998
__________________________________________________ ______

解决方案

On Tue, 10 Jun 2008 22:55:10 -0700, Jon Skeet [C# MVP] <sk***@pobox.com>
wrote:

[...]

>Please let me know what''s going wrong with my code and how to solve this
problem


Basically C# itself doesn''t believe the conversion is valid, but the
CLR is happy to do it.

I''m glad you''ve explained it (however briefly :) ). I just spent a fair
amount of time trying to integrate all of the different parts of the C#
spec that seem to address this, and all I could come up with was that it
shouldn''t work.

I am curious though: by what rule is the CLR allowed to override the C#
specification? Or, put another way, given that the CLR doesn''t check this
itself, why isn''t the C# compiler emitting the appropriate code to deal
with the situation?

If the C# spec had just left it as a general language semantics issue, I
could maybe see the current behavior. But the spec specifically says:

For an explicit reference conversion to succeed at run-time,
the value of the source operand must be null, or the _actual_
type of the object referenced by the source operand must be
a type that can be converted to the destination type by an
implicit reference conversion.

In this case, there is no implicit reference conversion that could convert
the actual type (uint[]) to the destination type (int[]). If the C# spec
is making statements regarding the _run-time_ behavior, it seems to me
that when the run-time doesn''t guarantee the behavior, the compiler needs
to.

I realize this is sort of an esoteric question, but I''m wondering if you
have any insight as to whether this is actually being considered a bug by
someone who matters (as opposed to me or the OP...I know _I_ think it''s a
bug), or is this something that a C# compiler person would claim is
working as intended?

Pete


On Jun 11, 7:19 am, "Peter Duniho" <NpOeStPe...@nnowslpianmk.com>
wrote:

Basically C# itself doesn''t believe the conversion is valid, but the
CLR is happy to do it.


I''m glad you''ve explained it (however briefly :) ). I just spent a fair
amount of time trying to integrate all of the different parts of the C#
spec that seem to address this, and all I could come up with was that it
shouldn''t work.

And indeed it doesn''t if you try to go straight from int[] to uint[] -
the compiler won''t let you. You have to go via Array, or Object, or
something like that.

I am curious though: by what rule is the CLR allowed to override the C#
specification? Or, put another way, given that the CLR doesn''t check this
itself, why isn''t the C# compiler emitting the appropriate code to deal
with the situation?

In short, the C# and CLR specs aren''t quite aligned on every aspect of
conversion. This is certainly unfortunate, but was likely to be the
case at some point.

If the C# spec had just left it as a general language semantics issue, I
could maybe see the current behavior. But the spec specifically says:

For an explicit reference conversion to succeed at run-time,
the value of the source operand must be null, or the _actual_
type of the object referenced by the source operand must be
a type that can be converted to the destination type by an
implicit reference conversion.

In this case, there is no implicit reference conversion that could convert
the actual type (uint[]) to the destination type (int[]). If the C# spec
is making statements regarding the _run-time_ behavior, it seems to me
that when the run-time doesn''t guarantee the behavior, the compiler needs
to.

Right. I think in this case the spec should explicitly call out that
the runtime is free to make more things valid. Otherwise it''s being
*very* prescriptive of the runtime.

I realize this is sort of an esoteric question, but I''m wondering if you
have any insight as to whether this is actually being considered a bug by
someone who matters (as opposed to me or the OP...I know _I_ think it''s a
bug), or is this something that a C# compiler person would claim is
working as intended?

I haven''t actually checked the CLI spec, but I''d certainly imagine
it''s allowed there. I suspect it would be deemed "working as expected,
but unfortunately misleading in the spec". I''ll raise it with the C#
team and see what they say. I would personally like it to stay as it
is - if the compiler generated extra checks around every conversion,
it would be painfully slow, just to make things fail in very
occasional situations. I''d much prefer the spec to have a caveat that
the conversion is guaranteed to succeed in situation X, but *may* also
succeed in other situations.

Jon


Hi KK,

I am sure you are running the code in unchecked mode otherwise the
statement

uint[] array = { uint.MinValue - 1, uint.MaxValue - 2 };

would have given you some compile error.

However that is not the cause for the issue you are facing.
There are two casting operations that this code does. First casting is
done when the uint[] is passed to method to Array. Second cast to
Array to int[], both are perfectly valid and so does the code.

If you want the first condition to be failed, try passing the unit[]
as uint[] itself.

public static void MyMethod(unit[] arr)
{
int[] afterCast1 = arr as
int[]; // This is an error.
if (null != afterCast1) //cast is successfull. Is it correct?
{
//DoSomeThing
}
}

Now you will hit by an error.

I hope this will help you!!!

-Cnu


这篇关于在值tye数组上使用as运算符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆