【问题标题】:Nullable int type allowed in Settings.settings?Settings.settings 中允许为 Null 的 int 类型吗?
【发布时间】:2010-09-08 13:07:18
【问题描述】:

我有一个属性,我想在我的 Settings.settings 文件中键入 int?。当我使用int? 时出现运行时故障:

System.NullReferenceException:对象引用未设置为对象的实例..

我可以使用字符串类型作为一种解决方法,在这种情况下检查 null 是否有效,但我必须解析字符串并在解析不起作用时处理错误。

能够将值设置为 null 允许我将属性记录在设置文件中,同时清楚地表明没有设置任何值。未设置时,我使用编程的默认值:

int? configuredNumberOfLimits = Settings.Default.RequiredNumberOfLimits;
if ( configuredNumberOfLimits == null  )
{
    requiredNumberOfLimits = DEFAULT_REQUIRED_NUMBER_LIMITS;
}

【问题讨论】:

  • @Gage:我认为这没有抓住重点。他希望设置定义int?

标签: c#


【解决方案1】:

有一种方法可以使用可空类型(即int?)进行设置 - 它需要对设置文件进行一些手动编辑,但之后在 VS 环境和代码中可以正常工作。并且不需要额外的函数或包装器。

为此,请创建一个具有所需名称的设置(例如 RequiredNumberOfLimit)并将其设置为任何类型(例如,为方便起见,标准 int)。 保存更改。

现在转到您的项目文件夹并使用文本编辑器(例如记事本)打开“Properties\Settings.settings”文件,或者您可以通过在解决方案资源管理器中右键单击“ - 在 VS 中打开它 - > 属性 -> Settings.settings”,选择“打开方式...”,然后选择“XML 编辑器”或“源代码(文本)编辑器”。 在打开的 xml 设置中找到您的设置(如下所示):

<Setting Name="RequiredNumberOfLimit" Type="System.Int32" Scope="User">
  <Value Profile="(Default)">0</Value>
</Setting>

将“类型”参数从 System.Int32 更改为 System.Nullable&lt;System.Int32&gt;。并清除默认值(因此默认情况下可以使用 null )。 现在这部分应该是这样的(注意&amp;lt;&amp;gt; 用于表示类型字符串中的&lt;&gt; 符号 - 这是为了通过 VS 正确解析 xml):

<Setting Name="RequiredNumberOfLimit" Type="System.Nullable&lt;System.Int32&gt;" Scope="User">
  <Value Profile="(Default)" />
</Setting>

现在保存更改并重新打开项目设置 - 瞧! - 我们有 System.Nullable&lt;System.Int32&gt; 类型的设置 RequiredNumberOfLimit,它被 VS 设置设计器正确解析,并且可以在代码中用作普通的 int? 变量。

如果您希望此设置能够返回null,则应保持默认值字段清晰。 否则,如果之前将其分配为 null,则此设置将返回默认值(但这就是默认值的工作方式,不是吗?:P)。

【讨论】:

  • 酷!像魅力一样工作!
  • 该方法适用于在设置设计器中查看设置并在代码中设置默认值。但是,当我进行此更改时,我的设置从 App.config 文件中消失了。在给定的上下文中,这可能重要也可能不重要,但我认为值得注意。
  • 补充@Brian 所说的话:是的,使用设置设计器进行编辑会清除 app.config 中的设置,但如果您将它们放回去,它们会再次从那里读取。所以,要么不要使用设计器,要么记得在使用后将设置放回去......有点痛苦,但就我而言,我认为这是值得的。
  • VS 2019 中的Settings Designer 似乎对可空类型没有任何问题,甚至将其添加到类型的下拉列表中。
  • @ThomasS.Trias,是的,9 年后,他们终于将它添加到 VS 设计器中:) 不过感谢您告知我们。
【解决方案2】:

怎么样:

int configuredNumberOfLimits

if(!int.TryParse(Settings.Default.RequiredNumberOfLimits, 
    out configuredNumberOfLimits))
{
   configuredNumberOfLimits = DEFAULT_REQUIRED_NUMBER_LIMITS;
}

这样您可以检查该值,如果失败则设置默认值。不用担心字符串或解析,或未处理的异常。

【讨论】:

  • 这就是我提到的解决方法。如果可能,我想避免解析。
  • 这个我没试过,但是你试过int吗? value = Settings... as (int)
【解决方案3】:

我认为你最好的选择是老式的bool/int 组合。这不是最漂亮的解决方案,但与int? 并没有什么不同

int configuredNumberOfLimits;
if (Settings.Default.HasRequiredNumberOfLimits)
{
    configuredNumberOfLimits = Settings.Default.RequiredNumberOfLimits;
}
else
{
    configuredNumberOfLimits = DEFAULT_REQUIRED_NUMBER_LIMITS;
}

【讨论】:

  • 谢谢。自 int?不是 Settings.settings 中受支持的类型,我的选择似乎是在您的建议和@Kevin 建议之间。
【解决方案4】:

您可以在 Settings.Designer.cs 中手动设置类型

例如:

    public decimal? Test{
        get {
            return ((decimal?)(this["Test"]));
        }
        set {
            this["Test"] = value;
        }
    }

【讨论】:

  • 这样做的问题是,每当您对“设置”选项卡进行更改时,您都必须返回到 Designer.cs 并再次更改类型。
  • 当然可以。就我而言,我很少更改它,这对我来说不是问题
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-20
  • 2017-01-26
  • 1970-01-01
  • 1970-01-01
  • 2010-11-30
相关资源
最近更新 更多