因为使用.NET 4.0中出现InvalidOperationException在Visual Studio的发行模式模式、NET、InvalidOperationException、Studio

2023-09-07 14:14:03 作者:久思成疾ら久病成医

我有一些麻烦,港口现有的.NET 3.5应用到.NET 4.0。在code不是我自己写的,所以我didn't详细了解为什么事情,因为它们。

I have some trouble to port an existing .NET 3.5 Application to .NET 4.0. The Code isn't written by myself so I didn´t know in detail why the things are as they are.

这是这种情况: 如果应用程序从Visual Studio启动(Release或Debug模式并不重要),并且如果在应用程序启动的形式调试文件夹code正常工作 现在的问题是发行部署,因为就是不会因为4.0正常工作(也是4.5): - /

This is the Situation: Code works fine if the application is started from Visual Studio (Release or Debug-Mode doesn’t matter) and also if the application is started form Debug-folder The Problem is the Release-deploy, because is doesn’t work well since 4.0 (and also in 4.5) :-/

这是初始呼叫:

someObject.Text = Elements.GetElement(Int16.Parse(cb1.Text));

和这里是code:

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
}

关键是返回BaseItemList.Single(V =&GT; v.Value == ID)。文; 。它抛出一个 InvalidOperationException异常,因为在Release 公共静态只读元素元素1 =创建(数字0,0)公共静态只读元素元素2 =创建(1号,1 ); 还没有准备好。在异常的时刻是BaseItemList空(BaseItemList.Count = 0)。 我不知道为什么会这样的发布形式仓文件夹,而不是在释放出的Visual Studio。 为了测试我停用优化code的项目属性,但它并不能帮助。

The key is return BaseItemList.Single(v => v.Value == id).Text;. It throws a InvalidOperationException, because in Release public static readonly Elements Element1 = Create("Number 0", 0); and public static readonly Elements Element2 = Create("Number 1", 1); aren't ready. In the moment of the Exception is BaseItemList empty (BaseItemList.Count = 0). I am not sure why this happened in release form bin-folder and not in release out of visual studio. For tests I deactivated "Optimize code" in project-properties but it doesn’t help.

当然,该结构是不是最好的,但我想知道什么是.NET 4.0带来了code奉承不同。

Surely the construct isn't the best, but I want to know what is different in .Net 4.0 that bring the code to flatter.

感谢您的帮助

推荐答案

我相信问题是,你依靠静态初始化为元素具有来看,尽管事实上,你有没有提到其中的任何领域。在一个类型的类型初始值不具有静态构造函数只保证前的第一个静态字段访问运行。在C#5规范的第10.5.5.1:

I believe the problem is that you're relying on the static initializer for Elements having run, despite the fact that you haven't referred to any fields within it. The type initializer in a type which doesn't have a static constructor is only guaranteed to run before the first static field access. Section 10.5.5.1 of the C# 5 specification:

如果一个静态构造函数(§10.12)存在于类中,执行静态字段初始发生前立即执行的静态构造函数。否则,静态字段初始是在之前第一次使用这个类的静态字段的实现相关的时间执行。

If a static constructor (§10.12) exists in the class, execution of the static field initializers occurs immediately prior to executing that static constructor. Otherwise, the static field initializers are executed at an implementation-dependent time prior to the first use of a static field of that class.

和第10.12节有:

的静态构造函数的封闭类类型在一个给定的应用领域执行最多一次。静态构造的执行由第一以下事件触发的应用程序域的内部产生:

The static constructor for a closed class type executes at most once in a given application domain. The execution of a static constructor is triggered by the first of the following events to occur within an application domain:   类类型的实例被创建。   任何类类型的静态成员的引用。   

的类型初始化changed在.NET 4 的,但它只是一个实现细节 - 你的code之前被打破了,你只是不知道它

The implementation of type initialization changed in .NET 4, but it was only an implementation detail - your code was broken before, you just didn't know it.

如果您改变code有:

If you change your code to have:

static Elements() {}

元素类的然后的,我相信它会工作 - 因为静态构造函数力型初始化之前发生,立即第一的成员的访问,而不是仅仅在某些时候第一的前场的访问。

in the Elements class, then I believe it will work - because static constructors force type initialization to occur before immediately the first member access, rather than just "at some point before the first field access".

我个人持怀疑态度的一般模式,但是这是一个稍微不同的问题。

Personally I'm dubious about the general pattern, but that's a slightly different matter.

 
精彩推荐
图片推荐