首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >自使用.Net 4.0以来,visual studio的发布模式下的InvalidOperationException

自使用.Net 4.0以来,visual studio的发布模式下的InvalidOperationException
EN

Stack Overflow用户
提问于 2013-01-24 15:10:56
回答 1查看 1.9K关注 0票数 18

我在将现有的.NET 3.5应用程序移植到.NET 4.0时遇到了一些问题。代码不是我自己写的,所以我不知道为什么事情是这样的。

情况是这样的:如果应用程序是从Visual Studio启动的(Release或Debug-Mode无关紧要),代码工作得很好,而且如果应用程序是从Debug-folder启动的,问题出在Release-deploy,因为从4.0 (以及4.5)开始,它不能很好地工作:-/

这是初始调用:

代码语言:javascript
复制
someObject.Text = Elements.GetElement(Int16.Parse(cb1.Text));

下面是代码:

代码语言:javascript
复制
public class Elements : EnumBase<int, Elements>
{
    public static readonly Elements Element1 = Create("Number 0", 0);
    public static readonly Elements Element2 = Create("Number 1", 1);

    private static Elements Create(string text, int value) 
    {
        return new Elements() { text = text, value = value };
    }

    public static String GetElement(int id)
    {

        // The Following Code safes the day and let the release deploy work fine.
        // It doesn´t matter if the condition becomes true or not to runtime.
        /* 
        if (id == 999999999)
        {
            Elements el = Element1;
        }
        */

        // Release deploy works also fine if you do the following line in a loop instead of linq.
        return BaseItemList.Single(v => v.Value == id).Text; 
    }
}

[Serializable()]
public class EnumBase<T, E> :  IEqualityComparer<E> 
        where E : EnumBase<T, E>
{
    private static readonly List<E> list = new List<E>();
    protected string text;
    protected T value;

    protected static IList<E> BaseItemList
    {
        get
        {
            return list.Distinct(new EnumBase<T, E>(false)).ToList();
        }
    }

    protected EnumBase()
    {
        list.Add(this as E);
    }

    /// <summary>
    /// Constructor for distinct to avoid empty elements in the list
    /// </summary>   
    private EnumBase(bool egal) {}

    public string Text
    {
        get { return text; }
    }

    public T Value
    {
        get { return value; }
    }


    #region IEqualityComparer<E> Member

    // ...

    #endregion
}

关键是return BaseItemList.Single(v => v.Value == id).Text;。它抛出一个InvalidOperationException,因为在发行版中public static readonly Elements Element1 = Create("Number 0", 0);public static readonly Elements Element2 = Create("Number 1", 1);还没有准备好。在异常发生的时刻,BaseItemList为空(BaseItemList.Count = 0)。我不确定为什么这发生在发布表单bin-folder中,而不是在visual studio的发布中。对于测试,我在project-properties中禁用了“优化代码”,但它没有帮助。

当然,这个结构不是最好的,但我想知道.Net 4.0中有什么不同之处,使代码变得更扁平化。

感谢你的帮助

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-01-24 15:17:34

我认为问题在于,尽管您没有引用Elements中的任何字段,但您仍然依赖于运行它的静态初始化器。没有静态构造函数的类型中的类型初始化器只能保证在第一次静态字段访问之前运行。

如果类中存在静态构造函数(§10.12),则在执行该静态构造函数之前立即执行静态字段初始化器。否则,静态字段初始化器在第一次使用该类的静态字段之前的依赖于实现的时间执行。

而第10.12节有:

封闭类类型的静态构造函数

在给定的应用程序域中最多执行一次。静态构造函数的执行由应用程序域中发生的下列事件中的第一个事件触发:

  • 创建类类型的实例。
  • 引用类类型的任何静态成员。

类型初始化changed in .NET 4的实现,但这只是一个实现细节-您的代码之前被破坏了,只是您不知道而已。

如果您将代码更改为:

代码语言:javascript
复制
static Elements() {}

Elements类中,我相信它会起作用--因为静态构造函数强制类型初始化发生在第一次成员访问之前,而不是“在第一次字段访问之前的某个时刻”。

就我个人而言,我对一般模式持怀疑态度,但这是一个略有不同的问题。

票数 21
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14495757

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档