如何将值标记为不应为空?

问题描述 投票:0回答:1

我有一个函数被正确指定为返回一个可能为空的对象。我的代码调用该函数,但调用方式不会返回 null。

MyClass? MyFunction(string x);
/* ... */
var myObject = MyFunction("Never return null.");
myObject.MyMemberFunctionOfMyClass();

Visual Studio(正确地)将 myObject 的使用标记为“可能的空引用”。 知道它永远不会为空,但编译器不知道。

有没有办法将其标记为已知不能为空?我知道我可以添加对 null 的测试,但这会重复编译器无论如何都会插入的 test-for-null/ throw-NullReferenceException 代码,并且如果没有它,我的函数将非常整洁。我也不想使用关闭警告的

#pragma
,因为我想保留其他值的警告。

我更喜欢某种方式将单个值包裹在“该值不会为空。继续。”的外衣中。

var myObject = MyFunction("Never return null.").NotNull();

有这样的事吗?

c# .net-core nullreferenceexception nullable nullable-reference-types
1个回答
0
投票

如果您确实确定某些内容不为 null,并且您不想为冗余的 null 检查付出性能成本,则可以随时使用

!
来抑制它。

var myObject = MyFunction("Never return null.")!;

您可以选择将其放入带有解释的包装函数中。

如果函数有时确实可以返回 null,那么也可以注释例如返回可能或可能不为 null 的条件。

    [return: NotNullIfNotNull(nameof(input))]
    public static string? Foo(string? input)
    {
        if (input == null) return null;
        else return input + "bar";
    }
    public static void Test()
    {
        string a = Foo(null); // Warning
        string b = Foo("hello"); // No warning
        string? c = Foo(null); // No warning
        string d = Foo(b); // No warning
        string e = Foo(c); // Warning
}

然而,这些的可能性相当有限。

不只是用

!
进行抑制的另一种选择是制作一个不返回 null 的函数版本,并且如果给定的输入可能导致 null,则抛出(或者如果确实想避免释放性能成本,则可能断言)。在最简单的情况下,这可能是一个包装器。提供更多保护,而不仅仅是消除警告。

public static string? MaybeNull(string input) // 3rd party thing you can't change
{
    if (input.Length < 5) return null;
    else return input;
}
public static string NeverNull(string input)
{
    if (input.Length < 5) throw new ArgumentException("Must be at least 5 characters.", nameof(input));
    string? ret = MaybeNull(input);
    Debug.Assert(ret != null);
    return ret!;
}
public static string NeverNull2(string input)
{
    string? ret = MaybeNull(input);
    if (ret == null) throw new ArgumentException("Invalid input.", nameof(input));
    return ret;
}
最新问题
© www.soinside.com 2019 - 2024. All rights reserved.