gpt4 book ai didi

C#类型转换不一致?

转载 作者:IT王子 更新时间:2023-10-29 04:06:18 24 4
gpt4 key购买 nike

在 C# 中,我无法将 long 隐式转换为 int

long l = 5;
int i = l; // CS0266: Cannot implicitly convert type 'long' to 'int'. An explicit conversion exists (are you missing a cast?)

这会产生上述错误。确实如此;如果我这样做,由于错误的截断,我有破坏数据的风险。如果我决定我知道我在做什么,那么我总是可以进行显式转换,并告诉编译器可以截断,我最清楚。

int i = (int)l;  // OK

但是,当使用 foreach 循环时,相同的机制似乎并不适用。

IList<long> myList = new List<long>();
foreach (int i in myList)
{
}

编译器甚至不会在这里生成警告,即使它本质上是同一件事:将 long 未经检查地截断为 int,这很可能破坏我的数据。

所以我的问题很简单:为什么这个 foreach 不会产生与变量赋值相同的错误?

最佳答案

更新:这个问题是 the subject of my blog in July of 2013 .感谢您提出很好的问题!

Why does this foreach not create the same error as the variable assignment does?

“为什么”的问题很难回答,因为我不知道你问的是什么“真正的”问题。因此,我不回答这个问题,而是回答一些不同的问题。

What section of the specification justifies this behaviour?

正如 Michael Liu 的回答正确指出的那样,它是第 8.8.4 节。

The whole point of an explicit conversion is that the conversion must be explicit in the code; that's why we have the cast operator; it's waving a big flag that says "there's an explicit conversion right here". This is one of the few times in C# where an explicit conversion is not extant in the code. What factors motivated the design team to invisibly insert an "explicit" conversion?

foreach循环是在泛型之前设计的。

ArrayList myList = new ArrayList();
myList.Add("abc");
myList.Add("def");
myList.Add("ghi");

你不想说:

foreach(object item in myList)
{
string current = (string)item;

在没有泛型的世界中,您必须提前知道列表中有哪些类型,而且您几乎总是知道。但此信息未在类型系统中捕获。因此,您必须以某种方式告诉编译器,您可以这样说

foreach(string item in myList)

这是您向编译器断言列表中充满了字符串,就像强制转换断言特定项目是字符串一样。

您完全正确,这是泛型世界中的错误特征。由于现在更改它会很麻烦,因此我们坚持使用它。

这个功能很困惑;当我第一次开始编写 C# 时,我假设它具有如下语义:

while(enumerator.MoveNext())
{
if (!(enumerator.Current is string) continue;
string item = (string)enumerator.Current;

也就是说,“对于这个列表中的每个字符串类型的对象,执行以下操作”,当它真的是“对于这个列表中的每个对象断言该项目是一个字符串并执行以下操作......”(如果前者是您真正想要的,然后使用 OfType<T>() 扩展方法。)

这个故事的寓意是:当您在版本 2 中大量更改类型系统时,语言最终会具有奇怪的“遗留”功能。

Should the compiler produce a warning for this case in modern code, where generics are being used?

我考虑过。我们的研究表明

foreach(Giraffe in listOfMammals)

如此普遍以至于大多数时候我们都会对正确的代码发出警告。这会给每个打开“警告作为错误”进行编译的人带来麻烦,而且通常来说,在代码上发出警告是不好的,可能有点臭,但实际上是正确的。我们决定不追究警告。

Are there other situations where the C# compiler invisibly inserts explicit conversions?

是的。事实上,就在这个问题之后的几个小时,有人问了一个问题:

Compiler replaces explicit cast to my own type with explicit cast to .NET type?

有一些极其模糊的互操作场景,其中也插入了显式转换。

关于C#类型转换不一致?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16421852/

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