如何在类中初始化非空字符串?

5

我有这个项目:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp3.0</TargetFramework>
    <Nullable>enable</Nullable>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Microsoft.Extensions.Hosting" Version="3.0.1" />
  </ItemGroup>
</Project>

这是主类:

namespace CSharp8
{
    using System;
    using Microsoft.Extensions.Configuration;

    internal class Program
    {
        private static void Main()
        {
            var configuration = new ConfigurationBuilder()
                .AddJsonFile("appsettings.json", false, true)
                .Build();
            var appSettings = configuration.Get<AppSettings>();
        }

        public class AppSettings
        {
            public string SourceServer { get; set; }
            public string TargetServer { get; set; }
        }
    }
}

这是appsettings.json文件:

{
  "SourceServer": "prodtools",
  "TargetServer": "qatools"
}

在AppSettings属性上,我收到了以下警告:

警告 CS8618 非可空属性“SourceServer”未初始化。 考虑将该属性声明为可空。

我可以通过不同的方式来解决这个问题。
1.
public class AppSettings
{
#pragma warning disable CS8618 // Non-nullable field is uninitialized. Consider declaring as nullable.
    public string SourceServer { get; set; }
    public string TargetServer { get; set; }
#pragma warning restore CS8618 // Non-nullable field is uninitialized. Consider declaring as nullable.
}

我不喜欢这个,因为我认为规则必须在整个项目中保持一致。
2. (待翻译)
public class AppSettings
{
    public string SourceServer { get; set; } = "";
    public string TargetServer { get; set; } = "";
}

我不喜欢这个,因为空字符串是错误的值。属性似乎被初始化了,但是值是没有意义的,如果我没有正确地初始化它们,它们将破坏我的程序。

3.

public class AppSettings
{
    public string SourceServer { get; set; } = null!;
    public string TargetServer { get; set; } = null!;
}

这是有道理的,实例被创建时是空值,但这些值会立即初始化。但我无法确保这段代码在将来不会出现问题,因为属性是非空的。
4.
public class AppSettings
{
    public string? SourceServer { get; set; }
    public string? TargetServer { get; set; }
}

这也是有道理的。在一微秒内,属性将保持为空。但是在我的程序中它们必须具有一个值。所以我也不喜欢这种方法。

你认为哪种方式更合适呢?还有其他建议吗?谢谢!

更新 现在我更喜欢这个方案。

#nullable disable warnings
public class AppSettings
{
    public string SourceServer { get; set; }
    public string TargetServer { get; set; }
}

我仍然会在非空属性中得到null值,这是无法避免的,但至少它让我免于写很多无意义的代码,例如 = null!;


5
我对你对3的论证并不满意,即我会选择第三个选项。设置必须在程序启动时立即设置,对吗?如果它们在程序运行时某种情况下没有被设置,那么很可能出了什么严重问题,因此你会希望它崩溃,表明发生了非常严重的问题。 - Sweeper
1
这个新的可空引用类型主要是为了显式表达。您不应依赖未编写的隐式默认值。因此,对于此操作,版本3可能最有意义。而且它是C#8之前任何版本的默认设置。版本4相当类似,只是以另一种方式表示“允许为空”——稍微不那么显式。如果您认为空值是例外而不是规则,请选择3。 - Holger
第三个选项对我来说看起来不错,但我们能确定它会永远有效吗?string s=null!听起来像int i=null!。很遗憾我在MSDN上找不到最佳实践。或者是我漏掉了什么? - pavok
1个回答

1
在这种情况下,我倾向于使用以下方式,但我想这是个人偏好的问题:
public class AppSettings
{
  public string SourceServer{ get; private set;} = string.Empty;
  public string TargetServer{ get; private set;} = string.Empty;
}

然后在使用这些值之前,我会检查它们的值。类似于:

var settings = new AppSettings();
if(string.IsNullOrWhitespace(settings.SourceServer)) 
{
 // Some error handling code
 return;
}

//process SourceServer value

我猜你在存储或使用数值之前已经进行了验证,所以这不是问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接