Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 静态对象为空/未在正确的时间初始化_C#_.net_Enums_Static_.net Micro Framework - Fatal编程技术网

C# 静态对象为空/未在正确的时间初始化

C# 静态对象为空/未在正确的时间初始化,c#,.net,enums,static,.net-micro-framework,C#,.net,Enums,Static,.net Micro Framework,我使用的是这里概述的。我需要将一个类型安全枚举嵌套到另一个类型安全枚举中。创建父构造函数时,子属性(静态对象)为NULL。似乎没有调用子构造函数,我遇到了一些错误。(我的父和子构造函数可能会混淆,但它解释了层次结构) 下面是一个示例(我正在使用netMF): 公共类MyDeviceSetting//parent { 公共只读字符串名称; 公共MyUnit设置单元; 公共只读MyUnit.UnitPurpose UnitPurpose; #区域我的静态设置 //单位设置 公共静态MyDeviceS

我使用的是这里概述的。我需要将一个类型安全枚举嵌套到另一个类型安全枚举中。创建父构造函数时,子属性(静态对象)为NULL。似乎没有调用子构造函数,我遇到了一些错误。(我的父和子构造函数可能会混淆,但它解释了层次结构)

下面是一个示例(我正在使用netMF):

公共类MyDeviceSetting//parent
{
公共只读字符串名称;
公共MyUnit设置单元;
公共只读MyUnit.UnitPurpose UnitPurpose;
#区域我的静态设置
//单位设置
公共静态MyDeviceSetting TempUnits=新MyDeviceSetting(“TempUnits”,MyUnit.mm);//MyUnit.mm为空。为什么?
公共静态MyDeviceSetting BLAH=新MyDeviceSetting(“BLAH”,MyUnit.inch);//MyUnit.inch为空。为什么?
#端区
/// 
///这是主私有构造函数
/// 
/// 
私有MyDeviceSetting(字符串名称,MyUnit defaultUnit)
{
名称=名称;
SettingUnit=defaultUnit;//空
UnitPurpose=SettingUnit.Purpose;//失败,因为SettingUnit为NULL
}
}
公共密封类MyUnit
{
私有静态整数计数=0;
//这些用于存储和识别内存中的单元
公共只读单元ID;
公共只读int-TestID;
公共枚举单位用途
{
距离,
速度
温度,
时间
时钟,
无单位
}
公共只读字符串DisplayName;
公共只读字符串缩写;
公共只读字符串名称;
公共只读单位目的;
#区域我的单位
公共静态只读MyUnit毫米=新的MyUnit(“毫米”、“毫米”、“毫米”、UnitPurpose.DISTANCE,1);
公共静态只读MyUnit英寸=新的MyUnit(“英寸”、“英寸”、“英寸”、UnitPurpose.DISTANCE,2);
#端区
私有MyUnit(字符串名称,
字符串显示名,
字符串缩写,
共同目标共同目标,
国际单位制)
{
名称=名称;
DisplayName=DisplayName;
缩写=缩写;
目的=统一目的;
UnitID=UnitID;
TestID=计数;
计数++;
}
}
如何确保
child
不为空?附近有工作吗?编辑:确保这应该正常工作,但在我的情况下,它不工作。

看来你的问题很难复制,任何方式都需要务实

您可以使
MyUnit
静态字段在
mydeviceset
静态字段设置之前初始化,只需首先调用
MyUnit

这很简单,只需在程序中的任何其他事情之前创建一个虚拟变量

public class MyDeviceSetting //parent
{
    static MyDeviceSetting()
    {
        var dummy = MyUnit.inch;
    }
}
因此,从不使用虚拟变量,而是初始化MyUnit的静态实例


在此之后,任何带有
MyDeviceSetting
的活动都将得到
MyUnit
初始化

这似乎是.Net Micro framework的一个缺陷/限制。它不完全支持静态构造函数。有人报告了同样的问题:

for NetCF 3.0包含以下警告:

不要使用静态构造函数。它们还没有完全得到.NET Micro Framework的支持

由此看来,对静态构造函数的调用(至少从2.0开始)是序列化的:

在.NET Compact Framework中,有些事情无法在中完成 在完整的.NET框架中可以使用的静态构造函数。 基本上,所有静态构造函数都是在序列化 NET Compact Framework V2中的时尚

那篇文章在死锁的背景下讨论了这一点,但我相信这就是它不起作用的原因

不幸的是,这意味着您不能依赖于静态,必须自己处理初始化和锁定。像这样的方法应该会奏效:

private static MyUnit inch;

public static MyUnit Inch
{
    get
    {
        if (inch == null)
            inch = new MyUnit("inch", "inch", "in", UnitPurpose.DISTANCE, 2);
         return inch;
    }
}

不幸的是,这会降低静态构造函数提供的线程安全性。这将很难解决,因为您不能依赖静态成员,因为正如我们所看到的,您不能依赖于对它们进行初始化。

除了@shf301及其工作不正常的原因之外,在编译时,构造函数似乎是以某种字母/字母数字顺序调用的

将子类重命名为
MyAUnit
会使其位于
MyDeviceSetting
之前,并且似乎会触发
MyAUnit
静态成员位于
MyDeviceSetting
静态成员之前


这似乎可行,但暂时有点“黑客行为”。

作为一种解决方法,您可以将
MyUnit
类移动到另一个名为MyUnit.cs的源文件中,这将导致.netmf CLR首先加载该类

我已经在运行.Netmf 4.3 RTM的环境中进行了测试。

您提供的代码不会编译,但在进行编译所需的细微更改后,它就可以正常工作了。请提供一个简短但完整的例子,实际说明问题所在。@JuanK这是作为一名教师的目的Enum@GusMofx我已经测试了你上次更新的代码,但一切看起来都很好,你告诉我们的代码必须失败或导致空。。。工作正常S@GisMofx有人在向构造函数传递null。我不知道为什么,因为您没有向我们展示该代码。在这种情况下,这听起来可能是netMF的错误。你应该在问题中提到这一点,并为它添加一个标签。我试过了。它仍然在父类之后初始化。这不应该发生。在哪里创建虚拟变量?只要在程序启动后执行的第一行代码中执行即可。@GisMofx我已经修改了代码,将虚拟变量放入MyDeviceSetting新的静态构造函数中。静态构造函数+虚拟初始化应该可以工作。您可以尝试使用netMF吗?让我们来调用sta
private static MyUnit inch;

public static MyUnit Inch
{
    get
    {
        if (inch == null)
            inch = new MyUnit("inch", "inch", "in", UnitPurpose.DISTANCE, 2);
         return inch;
    }
}