gpt4 book ai didi

c# - "as"运算符的意外行为,它与普通转换不同

转载 作者:太空狗 更新时间:2023-10-29 17:55:01 27 4
gpt4 key购买 nike

我问了this question .此代码无法编译(“无法将 Generic<T> 转换为 T),原因已解释为 here (即使我期望在运行时出现 InvalidCastException而不是编译时错误)。

class NonGeneric
{
}

class Generic<T> : NonGeneric
where T : NonGeneric
{
T DoSomething()
{
return (T)this; // ** Cannot convert...
}
}

接受的解决方案给出了这个解决方法:

T DoSomething()
{
return this as T;
}

我的问题是:为什么as运算符应该完全等同于强制转换运算符:

The as operator is like a cast operation. However, if the conversion isn't possible, as returns null instead of raising an exception.

如果this as T应该等同于 this is T? (T)this: (T)null那为什么as T作品和(T)this甚至不编译? AFAIK cast 可用于比 as 更广泛的情况:

Note that the as operator performs only reference conversions, nullable conversions, and boxing conversions. The as operator can't perform other conversions, such as user-defined conversions, which should instead be performed by using cast expressions.

那这是为什么呢?它是 as 的文档特征吗?运算符(operator)?它是泛型类型的编译器/语言限制吗?请注意,这段代码编译得很好:

return (T)((object)this);

这是因为编译器无法确定 T 是否存在是dynamic (即使有 where 约束)那么它总是会生成这样的代码吗?

最佳答案

它在 C# 语言规范(强调我的)中说,

If the compile-time type of E is not dynamic, the operation E as T produces the same result as E is T ? (T)(E) : (T)null except that E is only evaluated once. The compiler can be expected to optimize E as T to perform at most one dynamic type check as opposed to the two dynamic type checks implied by the expansion above.

If the compile-time type of E is dynamic, unlike the cast operator the as operator is not dynamically bound (§7.2.2). Therefore the expansion in this case is: E is T ? (T)(object)(E) : (T)null

这似乎是使用 as 或当 this 首先被转换为对象时编译成功的原因。此外,

In an operation of the form E as T, E must be an expression and T must be a reference type, a type parameter known to be a reference type, or a nullable type. Furthermore, at least one of the following must be true, or otherwise a compile-time error occurs:

• An identity (§6.1.1), implicit nullable (§6.1.4), implicit reference (§6.1.6), boxing (§6.1.7), explicit nullable (§6.2.3), explicit reference (§6.2.4), or unboxing (§6.2.5) conversion exists from E to T.

The type of E or T is an open type.

E is the null literal.

您的通用类的当前情况是什么。

关于c# - "as"运算符的意外行为,它与普通转换不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21432617/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com