如何将可为空的对象引用分配给不可为空的变量?

Tro*_*yvs 3 c# .net-assembly c#-8.0 nullable-reference-types

我正在使用 VS2019 并在项目设置中启用了可为空检查语义。我正在尝试使用程序集获取可执行文件的路径,如下所示:

        var assembly = Assembly.GetEntryAssembly();
        if (assembly == null)
        {
            throw new Exception("cannot find exe assembly");
        }
        var location = new Uri(assembly.GetName().CodeBase);//doesn't compile.
Run Code Online (Sandbox Code Playgroud)

它说,“assembly”是一个 [Assembly?] 类型,而 Uri ctor 需要一个字符串,编译错误是:

error CS8602: Dereference of a possibly null reference.
Run Code Online (Sandbox Code Playgroud)

如何修复我的代码以使其编译?非常感谢。

can*_*on7 6

您的问题是可以AssemblyName.CodeBase为空:它的类型为string?

您需要添加额外的代码来处理.CodeBaseis null(或用 抑制它!)的情况,例如:

var codeBase = Assembly.GetEntryAssembly()?.GetName().CodeBase;
if (codeBase == null)
{
    throw new Exception("cannot find exe code base");
}
var location = new Uri(codeBase);
Run Code Online (Sandbox Code Playgroud)

或者

var location = new Uri(assembly.GetName().CodeBase!);
Run Code Online (Sandbox Code Playgroud)

在这种情况下,您收到的实际警告与 无关assembly,它是:

警告 CS8604:“Uri.Uri(string uriString)”中的参数“uriString”可能存在空引用参数。

来源(展开右下角的“警告”窗格)。这告诉您问题在于传递给Uri构造函数的字符串,即从.CodeBase.


Pav*_*ski 6

您可以使用null-forgiving 运算符!告诉编译器CodeBase不能null

var location = new Uri(assembly.GetName().CodeBase!);
Run Code Online (Sandbox Code Playgroud)

或使用带有一些默认值的空合并运算符??

var location = new Uri(assembly.GetName().CodeBase ?? string.Empty);
Run Code Online (Sandbox Code Playgroud)

错误

CS8604:“Uri.Uri(string uriString)”中参数“uriString”的可能空引用参数

通常被视为警告,您似乎在项目设置中启用了此选项