为什么这个getter抛出StackOverflowException,但只有从一个项目调用时?

时间:2010-02-08 13:24:43

标签: .net winforms nunit stack-overflow

我有几个项目:

  • 定义Thingo(主要解决方案)
  • 的数据库接口项目
  • 定义ThingoChooser(插件解决方案)
  • 的逻辑项目
  • 引用逻辑项目的GUI项目(插件解决方案
  • 引用逻辑项目(插件解决方案)的测试项目

我正在调试插件,因此我运行主解决方案,将其当前工作目录设置为所有插件项目所针对的bin\Debug目录。主可执行文件在GUI程序集中找到插件类并显示其主要表单。

在测试项目中,此代码可以正常工作:

this.chooser = new ThingoChooser();
foreach (var thingo in this.chooser.AvailableThingos) {
    Console.WriteLine(release);
}

发布到我的GUI项目中的相同代码在StackOverFlowException返回时失败并显示AvailableThingos

ThingoChooser.AvailableThingos看起来像这样:

    public IEnumerable<Thingo> AvailableThingos {
        get {
            // Yes, it DEFINITELY case-matches the private variable,
            // NOT the public property. Oh, I wish this were that easy!
            return this.availableThingos;
        }

        private set {
            // ...
        }
    }

...以及我设置IEnumerable<Thingo>的哪种this.availableThingos

这是一个List<Thingo>

是的,我有一个WinForms应用程序在尝试StackOverFlowException时抛出List<T>:)

VS2008非常乐意让我在返回之前检查this.availableThingos。每次单击步骤按钮StackOverflowException时。它也发生在调试器之外。

我试过的死鸡的精细波浪,大多数由评论者建议,包括:

  • 查看循环的堆栈跟踪
  • AvailableThingos的返回类型更改为List<Thingo>
  • 删除var,以防隐式输入填满我
  • 使属性的后备存储变量public并直接命中
  • 将后备存储更改为List<T>
  • 删除LINQBridge并重新定位到.NET 3.5

更改没有帮助,堆栈跟踪不显示任何循环。在getter的}之后单击“Step Into”按钮后,我得到异常警告浮动读数:

  

StackOverflowException未处理

     

mscorlib.dll中出现未处理的“System.StackOverflowException”类型异常

当我切换到.NET 3.5 完全删除LINQBridge 将支持商店的类型更改为List<Thingo>时,该错误最为戏剧性em>和直接访问它只需从WinForms代码中尝试:

List<Thingo> thingos = this.chooser.availableThingos.ToList();

是的:在.ToList()上拨打List<Thingo>可能会导致StackOverflowException爆炸。

1 个答案:

答案 0 :(得分:0)

问题原因是引用上的复制本地设置

GUI项目对数据库接口项目的引用具有Copy Local set True。它对逻辑项目的引用具有Copy Local set False。我怀疑逻辑项目是从GUI项目看到的不同DLL返回Thingo的枚举。

(可能需要解决问题:调试时,我正在运行第五个项目,它动态加载GUI项目的DLL。第五个项目有自己的数据库接口项目DLL副本。)

测试项目为两个项目集True都设置了Copy Local。要么匹配有帮助,要么只是当前工作目录或路径中只有一个数据库接口DLL副本。

我很乐意接受描述为什么导致StackOverflowException的最佳答案。我非常喜欢DuplicateCopiesOfAssemblyYouDoofusException

作为参考,这里是参考地图及其复制本地设置:

主命令项目(在调试器下运行,从bin\Debug目录动态加载GUI项目):

  • 将数据库接口DLL与主可执行文件放在同一目录中。这是与提示路径中目标下面的所有数据库接口引用相同的目录。

GUI项目(配置失败):

  • ref→数据库项目:复制Local = True
  • ref→逻辑项目:复制Local = False

逻辑项目:

  • ref→数据库项目:复制Local = False

测试项目:

  • ref→逻辑项目:复制Local = True
  • ref→数据库项目:复制Local = True

在评论者的公平性中,直到五分钟前我才在问题中描述解决方案布局,所以我不能指望他们已经解决了。