如何在类中初始化不可为空的字符串?

pav*_*vok 5 c# string initialization non-nullable

我有这个项目:

<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>
Run Code Online (Sandbox Code Playgroud)

这是主要的类:

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; }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这是appsettings.json:

{
  "SourceServer": "prodtools",
  "TargetServer": "qatools"
}
Run Code Online (Sandbox Code Playgroud)

在 AppSettings 的属性上,我收到此警告:

警告 CS8618 不可为 null 的属性“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.
}
Run Code Online (Sandbox Code Playgroud)

我不喜欢这样,因为我相信规则必须在整个项目中保持一致。

2.

public class AppSettings
{
    public string SourceServer { get; set; } = "";
    public string TargetServer { get; set; } = "";
}
Run Code Online (Sandbox Code Playgroud)

我不喜欢这个,因为空字符串是错误的值。这些属性似乎已初始化,但这些值毫无意义,如果我未能正确初始化它们,它们将破坏我的程序。

3.

public class AppSettings
{
    public string SourceServer { get; set; } = null!;
    public string TargetServer { get; set; } = null!;
}
Run Code Online (Sandbox Code Playgroud)

这是有道理的,实例是用空值创建的,并且这些值立即被初始化。但我不能确定这段代码将来不会中断,因为这些属性是不可为空的。

4.

public class AppSettings
{
    public string? SourceServer { get; set; }
    public string? TargetServer { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

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

你认为哪一种方式最有风水呢?还有其他建议吗?谢谢你!

更新这是我现在更喜欢的。

#nullable disable warnings
public class AppSettings
{
    public string SourceServer { get; set; }
    public string TargetServer { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

我仍然在不可为空的属性中获得空值,这是不可避免的,但至少它使我免于许多无意义的代码,例如 = null!;

Chr*_*sBD 1

在这种情况下,我倾向于使用以下内容,但我想这是一个偏好问题:

public class AppSettings
{
  public string SourceServer{ get; private set;} = string.Empty;
  public string TargetServer{ get; private set;} = string.Empty;
}
Run Code Online (Sandbox Code Playgroud)

然后在使用任何一个值之前我会检查它们的值。就像是

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

//process SourceServer value
Run Code Online (Sandbox Code Playgroud)

我想您在存储或使用它之前已经验证了该值,所以这不是问题。