c# - 如何将可空类型隐式转换为不可空类型

标签 c# .net

我有一个可空的 c# 10 .net 6 项目,其扩展方法为 ThrowIfNull

using System;
using System.Runtime.CompilerServices;

#nullable enable
public static class NullExtensions
{
    public static T ThrowIfNull<T>(
        this T? argument, 
        string? message = default, 
        [CallerArgumentExpression("argument")] string? paramName = default
    )
    {
        if (argument is null)
        {
            throw new ArgumentNullException(paramName, message);
        }
        else
        {
            return argument;
        }
    }
}

扩展方法将 string? 隐式转换为 string 但它不适用于其他基本类型,如 int?bool ?

public class Program
{
    public static void Main()
    {
        Console.WriteLine("Hello World");
        
        string? foo = "foo";
        string nonNullableFoo = foo.ThrowIfNull();  // success from "string?" to "string"
        Console.WriteLine(nonNullableFoo);
        
        bool? baz = true;
        bool nonNullableBaz = baz.ThrowIfNull();    // success from "string?" to "string"
        Console.WriteLine(nonNullableFoo);
        
        int? bar = 2;
        int nonNullableBar = bar.ThrowIfNull(); // error: Cannot implicitly convert type 'int?' to 'int'
        Console.WriteLine(nonNullableBar);
    }
}

如何使扩展隐式转换 int?bool?

这是完整的 dotnet fiddle https://dotnetfiddle.net/LiQ8NL

最佳答案

您可以通过为不可为 null 的引用类型提供一种扩展方法和为非托管(例如 int、bool 等)类型提供另一种扩展方法来实现您的目标。请注意,非托管类型需要强制转换。

public static class NullExtensions
{
    public static T ThrowIfNull<T>(
        this T? argument,
        string? message = default,
        [CallerArgumentExpression("argument")] string? paramName = default
    ) where T : notnull
    {
        if (argument is null)
        {
            throw new ArgumentNullException(paramName, message);
        }
        else
        {
            return argument;
        }
    }

    public static T ThrowIfNull<T>(
        this T? argument,
        string? message = default,
        [CallerArgumentExpression("argument")] string? paramName = default
    ) where T : unmanaged
    {
        if (argument is null)
        {
            throw new ArgumentNullException(paramName, message);
        }
        else
        {
            return (T)argument;
        }
    }
}

像这样使用:

int? foo = 42;
int bar = foo.ThrowIfNull();
Console.WriteLine(bar);

string? baz = "Hello";
string quus = baz.ThrowIfNull();
Console.WriteLine(quus);

// Comment out either this
baz = null;
quus = baz.ThrowIfNull();
// Or this
foo = null;
bar = foo.ThrowIfNull();

关于c# - 如何将可空类型隐式转换为不可空类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70430422/

相关文章:

c# - 可以将参数传递给 WPF 用户控件吗?

c# - ClosedXML 预定义样式

c# - 使用 Visual Studio 2010 和 HG 进行版本控制

c# - 移动 Azure 服务 C# .NET 后端补丁未更新

css - 基于 View (子页面)在 Layout.cshtml 中使用不同的 css 类渲染 <body> 标签?

c# - 方法或操作未实现

c# - 为什么 C# 在我的 ItemTemplates 中期望 ";"?

c# - 画棋盘

.net - System.Uri实现ISerializable,但给出错误?

.net - 什么定义了 VS2012 数据库项目中脚本的执行顺序?