You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何设置string类型为非可空(不可为null)?

C#非空字符串属性实现方案(替代手动空校验)

你需要实现「未标记nullable的属性必须持有有效值,标记nullable的属性允许为null」的规则,完全可以依托C#本身的能力和框架机制实现,不需要在业务代码里零散写string.IsNullOrEmpty()判断,下面是可直接落地的方案,按落地成本从低到高排序:

1. 开启可空引用类型编译检查(零成本基础方案)

C# 8.0及以上版本原生支持可空引用类型(NRT),只需要在项目的.csproj文件中添加如下配置,就能打开编译期的空值检查:

<PropertyGroup>
  <Nullable>enable</Nullable>
</PropertyGroup>

开启后编译器默认将所有未加?标记的引用类型识别为不可空类型,尝试给这类属性赋值null、或者未初始化就使用时,编译器会直接抛出警告,在编码阶段就能拦掉大部分空值问题。
对应你给出的实体属性,代码可以直接写成这样:

public class Book
{
    // 只读属性
    public int Id { get; }
    // 未加?标记,编译器默认要求非空
    public string Title { get; set; }
    public string Author { get; set; }
    public int PageCount { get; set; }
    public int TimesBorrowed { get; set; }
    // 加?标记为可空,允许赋值null
    public string? Borrower { get; set; }
    public DateTime? BorrowDate { get; set; }
    public DateTime? DueDate { get; set; }

    // 构造函数初始化必填非空属性,编译器会自动检查是否所有非空属性都被赋值
    public Book(int id, string title, string author, int pageCount)
    {
        Id = id;
        Title = title;
        Author = author;
        PageCount = pageCount;
        TimesBorrowed = 0;
    }
}

注意:这个方案是编译期检查,如果涉及反射、反序列化(比如数据库查询结果转实体、接口参数反序列化)等场景,运行时可能绕过编译器检查给属性注入null,需要搭配运行时校验兜底。

2. 实体内部收敛校验逻辑(无额外依赖的运行时兜底)

把空校验逻辑直接写在属性的setter和构造函数里,不需要在业务代码中重复写判断,所有赋值操作都会自动走校验:

private string _title;
public string Title
{
    get => _title;
    set => _title = string.IsNullOrEmpty(value)
        ? throw new ArgumentException("书名不能为空", nameof(value))
        : value;
}

private string _author;
public string Author
{
    get => _author;
    set => _author = string.IsNullOrEmpty(value)
        ? throw new ArgumentException("作者不能为空", nameof(value))
        : value;
}

只要有代码尝试给Title、Author赋值null或者空字符串,会在赋值环节直接抛出异常,不会让脏数据流入业务逻辑。如果用C# 11及以上版本,可以搭配required关键字修饰必填属性,进一步强制要求初始化时必须给这些属性赋值。

3. 数据注解校验(适配框架的最简方案)

如果你做的是Web项目、或者用EF Core做数据访问,直接用内置的数据注解标记必填属性即可,框架会自动完成校验,不需要自己写判断逻辑:

using System.ComponentModel.DataAnnotations;

public class Book
{
    public int Id { get; set; }

    [Required(ErrorMessage = "书名不能为空")]
    public string Title { get; set; } = string.Empty;

    [Required(ErrorMessage = "作者不能为空")]
    public string Author { get; set; } = string.Empty;

    public int PageCount { get; set; }
    public int TimesBorrowed { get; set; }
    public string? Borrower { get; set; }
    public DateTime? BorrowDate { get; set; }
    public DateTime? DueDate { get; set; }
}

接口请求进来时,ASP.NET Core会自动校验带[Required]标记的属性是否为空,校验不通过会直接返回参数错误;EF Core生成数据库迁移时,也会自动将这些字段配置为非空列,从数据库层面再做一层空值拦截。

4. 自定义非空字符串值类型(强约束方案)

如果想从类型根源上彻底杜绝空值,可以封装一个专门的非空字符串值类型,所有要求非空的字段都用这个类型替代原生string:

public readonly struct NonEmptyString
{
    public string Value { get; }
    public NonEmptyString(string value)
    {
        if (string.IsNullOrEmpty(value))
            throw new ArgumentException("字符串不能为空", nameof(value));
        Value = value;
    }

    // 配置隐式类型转换,减少使用时的类型转换代码
    public static implicit operator string(NonEmptyString s) => s.Value;
    public static implicit operator NonEmptyString(string s) => new(s);
}

使用时直接将Title、Author的类型声明为NonEmptyString即可,任何尝试给这类属性传null或者空串的操作,都会在实例创建时直接抛出错误,完全不存在空值漏判的可能。

选型建议:大学课程项目不需要过度设计,用「开启可空引用类型 + 数据注解/setter校验」的组合就足够,既可以在编码阶段靠编译器提示减少空值bug,运行时也有兜底校验,完全不需要在业务逻辑里零散写空判断。

内容的提问来源于stack exchange,提问作者Het Patel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 21:36:17