Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/281.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.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# “的意外行为”;作为「;运算符,它不同于普通转换_C#_.net_Casting - Fatal编程技术网

C# “的意外行为”;作为「;运算符,它不同于普通转换

C# “的意外行为”;作为「;运算符,它不同于普通转换,c#,.net,casting,C#,.net,Casting,我问。由于解释的原因,此代码无法编译(“无法将泛型转换为t”)(即使我希望在运行时出现无效异常,而不是编译时错误) 我的问题是:为什么as运算符应与cast运算符完全等效: as运算符类似于强制转换操作。但是,如果转换不可能,as将返回null而不是引发异常 如果这作为T应该等同于这是T?(T) 这:(T)null那么为什么因为T起作用而(T)这甚至不编译?AFAIK cast可用于比as更广泛的情况: 请注意,as运算符仅执行引用转换、可为null的转换和装箱转换。as运算符不能执行其他转换,

我问。由于解释的原因,此代码无法编译(“无法将
泛型
转换为
t
”)(即使我希望在运行时出现
无效异常
,而不是编译时错误)

我的问题是:为什么<代码>as运算符应与cast运算符完全等效:

as运算符类似于强制转换操作。但是,如果转换不可能,as将返回null而不是引发异常

如果
这作为T
应该等同于
这是T?(T) 这:(T)null
那么为什么
因为T
起作用而
(T)这
甚至不编译?AFAIK cast可用于比
as
更广泛的情况:

请注意,as运算符仅执行引用转换、可为null的转换和装箱转换。as运算符不能执行其他转换,例如用户定义的转换,而应该使用强制转换表达式执行这些转换

那为什么呢?它是
as
操作员的记录功能吗?它是泛型类型的编译器/语言限制吗?请注意,此代码可以很好地编译:

return (T)((object)this);
这是因为编译器无法确定
t
是否是
动态的
(即使在
中存在
约束),那么它将始终生成这样的代码?

根据:-

as运算符类似于强制转换操作。但是,如果转换不可能,as将返回null而不是引发异常

该代码与以下表达式等效,只是表达式变量只计算一次

另一个区别是:-

请注意,as运算符仅执行引用转换、可为null的转换和装箱转换。as运算符不能执行其他转换,例如用户定义的转换,而应该使用强制转换表达式执行这些转换

它在C语言规范(emphasis mine)中说

如果编译时类型E不是动态的,那么操作E as T将产生与相同的结果 E是T吗?(T) (E):(T)无效 除了E只计算一次。编译器可以将E优化为T,以执行最多一个动态类型检查,而不是上面扩展所暗示的两个动态类型检查

如果E的编译时类型为
动态
,则与cast运算符不同,
as
运算符不动态绑定(§7.2.2)。因此,这种情况下的扩展是:
E是T吗?(T) (对象)(E):(T)空

这似乎是使用
as
或将
首先强制转换到对象时编译成功的原因。此外,

在形式为
E as T
的操作中,
E
必须是表达式,
T
必须是引用类型、已知为引用类型的类型参数或可为空的类型。此外,必须至少满足以下条件之一,否则会发生编译时错误:

•标识(§6.1.1)、隐式可空(§6.1.4)、隐式引用(§6.1.6)、装箱(§6.1.7)、显式可空(§6.2.3)、显式引用(§6.2.4)或取消装箱(§6.2.5)存在从
E
T
的转换

类型
E
T
为开放式。

E
null
文本

这是泛型类的当前情况。

C#中的“as”操作符执行以下操作:-

  • 如果给定变量不是其任何基类型的给定类型,则返回null。它不会抛出任何异常
  • 只能与引用类型变量一起应用
  • “as”不进行任何转换(隐式/显式)

  • “as”运算符比任何强制转换都要快一些(即使在没有无效强制转换的情况下,也会由于异常而严重降低强制转换的性能)。

    编译错误表示您正在继承
    非通用的
    。是编译器混淆了,还是代码示例不准确?
    DoSomething()
    函数是否返回
    T
    对象或
    null
    ?@KeithPayne抱歉,错误消息。fixed@Adriano你能澄清你的问题为什么吗?为什么?@Adriano:related:-1不,这是我所期望的,但它不是等价的,因为(类型)表达式甚至无法编译。这就是为什么我的问题…它无法编译,因为编译器知道强制转换将失败(在编译时),但在
    as
    的情况下,它可以选择返回null(如果强制转换失败),因此它可以成功编译。不,强制转换可能在运行时失败。它不应该拒绝它(另一种情况请参见编辑)。至少它应该拒绝cast和“as”操作符……在我的例子中,它不是动态的,但我想编译器不会因此而抱怨!非常感谢。头奖我很确定MSDN文档没有包含这个小细节。为什么强调
    动态
    ?我不知道DLR是如何涉及到这里的。因为在这种情况下(表达式是
    动态的
    或者,我假设,
    泛型的
    ),在转换为
    t
    之前,
    as
    操作符将首先将表达式转换为
    对象
    。它解释了为什么使用
    作为表达式
    (T)((对象)表达式)
    是允许的,而
    (T)表达式
    是不允许的。@RitchMelton是的,即使不应该,因为这里我们只有泛型,没有动态,如果没有其他东西的话……我想这是编译器的问题。。。
    T DoSomething()
    {
        return this as T;
    }
    
    return (T)((object)this);
    
        expression is type ? (type)expression : (type)null