C# 自使用.Net 4.0后,visual studio的发布模式中出现InvalidOperationException

C# 自使用.Net 4.0后,visual studio的发布模式中出现InvalidOperationException,c#,linq,.net-4.0,enums,release,C#,Linq,.net 4.0,Enums,Release,我很难将现有的.NET3.5应用程序移植到.NET4.0。代码不是我自己写的,所以我不知道为什么事情是这样的 情况就是这样: 如果应用程序是从VisualStudio启动的(发布或调试模式无关紧要),并且应用程序是从调试文件夹启动的,则代码工作正常 问题在于版本部署,因为自4.0(以及4.5)以来,is无法正常工作:-/ 这是第一个电话: someObject.Text = Elements.GetElement(Int16.Parse(cb1.Text)); 代码如下: public cla

我很难将现有的.NET3.5应用程序移植到.NET4.0。代码不是我自己写的,所以我不知道为什么事情是这样的

情况就是这样: 如果应用程序是从VisualStudio启动的(发布或调试模式无关紧要),并且应用程序是从调试文件夹启动的,则代码工作正常 问题在于版本部署,因为自4.0(以及4.5)以来,is无法正常工作:-/

这是第一个电话:

someObject.Text = Elements.GetElement(Int16.Parse(cb1.Text));
代码如下:

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
}
公共类元素:EnumBase
{
公共静态只读元素Element1=Create(“数字0”,0);
公共静态只读元素Element2=Create(“数字1”,1);
创建私有静态元素(字符串文本、int值)
{
返回新元素(){text=text,value=value};
}
公共静态字符串GetElement(int id)
{
//下面的代码保证了一天的安全,并让发布部署工作正常。
//在运行时,条件是否为真并不重要。
/* 
如果(id==99999999)
{
元素el=元素1;
}
*/
//如果在循环中执行以下行而不是linq,则ReleaseDeploy也可以正常工作。
返回BaseItemList.Single(v=>v.Value==id).Text;
}
}
[可序列化()]
公共类枚举库:IEqualityComparer
其中E:EnumBase
{
私有静态只读列表=新列表();
受保护的字符串文本;
保护T值;
受保护的静态IList BaseItemList
{
得到
{
return list.Distinct(new EnumBase(false)).ToList();
}
}
受保护的EnumBase()
{
列表。添加(此为E);
}
/// 
///distinct的构造函数,以避免列表中的空元素
///    
私有枚举库(bool egal){}
公共字符串文本
{
获取{返回文本;}
}
公共价值
{
获取{返回值;}
}
#地区资格比较成员
// ...
#端区
}
键是
returnbaseitemlist.Single(v=>v.Value==id).Text。它抛出一个
InvalidOperationException
,因为在发布中
公共静态只读元素Element1=Create(“数字0”,0)
公共静态只读元素Element2=Create(“数字1”,1)未准备好。在异常时刻,BaseItemList为空(BaseItemList.Count=0)。
我不知道为什么这发生在发布表单bin文件夹中,而不是在VisualStudio的发布中。
对于测试,我停用了项目属性中的“优化代码”,但它没有帮助

当然,这种构造不是最好的,但我想知道.NET4.0中有什么不同之处,使代码更加平淡


感谢您的帮助

我相信问题在于,您依赖于已运行的
元素的静态初始值设定项,尽管您没有引用其中的任何字段。没有静态构造函数的类型中的类型初始值设定项只能保证在第一次静态字段访问之前运行。C#5规范第10.5.5.1节:

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

第10.12节规定:

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

  • 将创建类类型的实例
  • 引用类类型的任何静态成员
类型初始化的实现,但它只是一个实现细节——您的代码以前被破坏了,您只是不知道而已

如果您将代码更改为:

static Elements() {}
Elements
类中,我相信它会起作用——因为静态构造函数强制类型初始化在第一个成员访问之前发生,而不仅仅是“在第一个字段访问之前的某个点”


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

变量GetHashCode通常是危险的。你能发布完整的堆栈框架吗?嗨,西蒙,GetHashCode危险的原因是什么?***********异常文本***************System.InvalidOperationException:序列在System.Linq.Enumerable.Single[TSource](IEnumerable
1 source,Func
2谓词)测试时不包含匹配的元素。Form1.button1\u单击d:\Test\Projects\Test\Test\Form1.cs中的(对象发送者,事件参数e):System.Windows.Forms.Button.OnMouseUp第16行在System.Windows.Forms.Control.WmMouseUp(Message&m,MouseButtons按钮,Int32点击)在System.Windows.Forms.Control.WndProc(Message&m)…我没有说GetHashCode是危险的,我说的是“变量GetHashCode”,它在对象的生命周期内不应该变化。请看:好的,我明白了。谢谢Simon的链接。