Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/297.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么';as';关键字起作用,而()强制转换不起作用_C#_Asp.net - Fatal编程技术网

C# 为什么';as';关键字起作用,而()强制转换不起作用

C# 为什么';as';关键字起作用,而()强制转换不起作用,c#,asp.net,C#,Asp.net,我想知道为什么会这样 编辑: 如果我调试'as'关键字语句,我永远不会得到空引用(对象总是正确分配的)。但是()强制转换会创建异常,除非它具有if语句 编辑:在类中运行大约15次后,我能够得到一个空值。与()强制转换捕获异常的速度相比,似乎需要更多的运行才能找到null OLD:当类每次运行断点命中时在“as”语句处都有调试时-从不为null 如果在if中的“()”语句中有调试,则每次断点命中转换时,转换都会正常工作。Werid如果使用“as”运算符,如果转换失败,它只返回null。如果执行显式

我想知道为什么会这样

编辑:

如果我调试'as'关键字语句,我永远不会得到空引用(对象总是正确分配的)。但是()强制转换会创建异常,除非它具有if语句

编辑:在类中运行大约15次后,我能够得到一个空值。与()强制转换捕获异常的速度相比,似乎需要更多的运行才能找到null

OLD:当类每次运行断点命中时在“as”语句处都有调试时-从不为null


如果在if中的“()”语句中有调试,则每次断点命中转换时,转换都会正常工作。Werid

如果使用“as”运算符,如果转换失败,它只返回null。如果执行显式强制转换,如果转换失败,它将抛出异常。在这种情况下,“as”将被降级为预期的正确类型。显式转换无法向上移动到所需的类型

一般来说,除非您确实需要显式转换(例如,当您需要转换为值类型时),否则您应该始终执行“As”

使用as运算符不同于 以三种重要方式在C#中铸造:

当您输入变量时,它返回null 正在尝试转换的不是 请求的类型或在其继承中 链子,而不是扔一个 例外。它只能应用于 引用类型变量转换为 引用类型。随意使用 执行用户定义的转换,例如 作为隐式或显式转换 运算符,将使用哪种强制转换语法 做事实上,有两种完全不同的方法 IL中定义的不同操作 处理这两个关键字的 castclass和isinst说明)- 这不仅仅是“语法糖” 由C#编写以获得不同的结果 行为。as运算符似乎 在的v1.0和v1.1中稍微快一点 微软的CLR与铸造相比 (即使在没有 无效的铸型将严重影响 由于以下原因,铸件性能降低 例外情况)


使用
as
尝试将该对象强制转换为该特定类型,但失败时返回
null
,而不是引发异常(而强制转换只引发异常)。您确定带有
as
子句的对象实际返回的是非空对象吗

//始终有效,将有效对象返回到_页面 _page=\u httpContext.Handler作为System.Web.UI.page

这在技术上不起作用。如果您注意到
\u页面
将为
。它只是没有抛出一个错误

as
操作符用于告诉应用程序“我希望您尝试并转换它。它可能不会,我知道这一点,所以不要抛出异常。我将相应地处理它。”

()
转换用于告诉应用程序,“此对象将强制转换为此类型。如果它不正确,则说明有问题,我需要了解它。”

这两种类型之间的区别(以及你应该使用它们的时间)是当你“认为”某些东西可以铸造到另一种类型时,以及当你“知道”某些东西可以铸造到另一种类型时

以下是Eric Lippert关于该主题的一篇文章(改为他的博客,未重新反馈):
和@Tejs answer说的一样。将
转换为
时失败将生成空值

不过我要说的和他不同,作为一般规则,你应该总是使用明确的演员阵容。我个人更希望在转换失败的地方得到一个异常,而不是在另一个页面中得到一个(似乎)突然出现的空引用异常

不过,
as
运算符的一个很好的用途是在从数据库中转换内容时,不希望检查
System.DBNull

                //Fixes the problem
            if(_httpContext.Handler is System.Web.UI.Page)
            _page = (System.Web.UI.Page)_httpContext.Handler;

as cast和prefix cast之间的一个主要区别是前缀cast将引发异常,而as cast将只返回null。

正如许多人指出的那样,
as
操作符在这种情况下返回了
null
,避免了“问题”,但实际上没有“工作”

本网站详细介绍了使用
as
和铸造之间的3个区别:


事实上,这正是应该发生的事情。强制转换失败并引发错误,因为强制转换无效。如果强制转换失败,
as默认默认为null。

正如其他答案所指出的,它归结为一个事实,“as”在发生无效强制转换时将返回null,而显式强制转换将抛出异常

其他答案在是否向一个或另一个倾斜的问题上存在一些争论。如果要使用“as”,您需要在某个时候处理它可能是null的事实。如果要使用显式强制转换,则必须处理可能的异常。根据用例的不同,我倾向于这样或那样


当我知道强制转换可以工作但编译器不能工作时,我倾向于使用特定的强制转换,并且抛出异常也可以(因为这是一种例外情况)。但是,如果强制转换有合法的机会无效,我更喜欢使用“as”并测试null。这样可以避免捕获异常,因为异常更难看,调试也更困难。

但是为什么强制转换不起作用呢?我知道处理程序是System.Web.UI.Page。我也在谷歌上搜索并阅读了你发布的内容。仍然-没有意义。“它只能应用于转换为引用类型的引用类型变量”实际上不是真的-值可以是任何类型,目标类型也可以是可为空的值类型。因此,例如,
(int)0作为IEquatable
是有效的,特别是
(object)o作为int?
是检查
o
是否是装箱的
int
的好方法,而不会捕获异常。它还允许您将诸如
(T?)x作为U?
来编写,这可以稍微简化
                //Fixes the problem
            if(_httpContext.Handler is System.Web.UI.Page)
            _page = (System.Web.UI.Page)_httpContext.Handler;
int someint = cmd.ExecuteScalar() as int? ?? 0;