c# - 相同的代码在不同的机器上表现不同 - 可能是什么原因? (CLR 版本问题?)

标签 c# .net clr

我刚刚调试完一个问题,我们的程序在生产服务器上崩溃,但从未在开发机器上崩溃。

我制作了这个小程序,我可以用它重现问题:

using System;
using System.Collections.Generic;
using System.Linq;

namespace RunTimeBug
{
    class Program
    {
        static void Main(string[] args)
        {
            var coll = new Collection {{"Test", new Data()}, {"Test2", new Data()}};

            var dataSequence = coll.Cast<Data>().ToList();
            Console.WriteLine(dataSequence.Count);
        }
    }

    class Collection : Dictionary<string,Data>, IEnumerable<Data>
    {
        public new IEnumerator<Data> GetEnumerator()
        {
            foreach(var v in Values)
                yield return v;
        }
    }

    class Data { }
}

在我的机器上运行时,此代码打印“2”。在生产服务器上运行时,它失败并出现以下异常:

Unhandled Exception: System.InvalidCastException: Unable to cast object of type 'System.Collections.Generic.KeyValuePair
`2[System.String,RunTimeBug.Data]' to type 'RunTimeBug.Data'.
   at System.Linq.Enumerable.<CastIterator>d__b0`1.MoveNext()
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
   at RunTimeBug.Program.Main(String[] args)

我能在这些机器上找到的唯一区别是,CLR 运行时在机器上是 2.0.50727.4927 版,它可以工作,而在它不工作的机器上是 2.0.50727.1433 版。

据我所知,Cast 扩展方法在旧机器上获取错误版本的 IEnumerable,但在新机器上获取“正确”版本。

谁能解释为什么我会看到这个? 2 个 CLR 运行时版本之间发生了什么变化,这可能是造成这种情况的原因?

请注意,我已经部署了一个修复程序,并且我知道上面代码中的 Collection 类设计不佳,因为它实现了 2 个不同的 IEnumerable。这是在我们的产品中“在野外”发现的,所以我真的很想知道确切的原因。

最佳答案

我认为 Jason 链接到的文章中提到的修复与您在更高版本上运行的代码有关。我无权访问 Enumerable.Cast 的 SP1 之前版本,因此有点难以猜测。

有一件事是肯定的:一旦代码进入 Enumerable.CastIterator() ,那么它肯定不会在您的情况下工作。这会设置一个迭代器以将 IEnumerable 转换为 IEnumerable<>,并且该迭代器调用 GetEnumerator() 来初始化迭代器 block 。那只能调用 Dictionary.GetEnumerator(),而不是你的。将此 IEnumerable 返回的 KeyValuePair 转换为 Data 当然会失败,正如异常告诉您的那样。

当前版本的 Enumerable.Cast() 首先尝试将 IEnumerable 转换为 IEnumerable<>。那行得通。未使用 CastIterator()。

关于c# - 相同的代码在不同的机器上表现不同 - 可能是什么原因? (CLR 版本问题?),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1827007/

相关文章:

c# - 计算数据库中检索到的行

c# - 读取 JSON 对象

c# - 为什么 Nullable<T> 是一个结构体?

c# - HttpClient不报告从Web API返回的异常

c# - 无法将属性或索引器 'System.DateTime.TimeOfDay' 分配给 — 它是只读的

.net - 将 DataContext 绑定(bind)到 ValidationRule

c# - 来自 C# 的 DVD ISO - .NET DiscUtils 替代品

c# - Azure DocumentDB 十进制截断

c# - Garbage Collection Modes : If 2 apps exist on a server, "Server Mode"难道是劫以还债?

c# - 在 C# 中调用 C++ 导出的函数