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

将JSON中带const的anyOf枚举结构序列化到C#的最优方案

问题背景

我正在编写C#程序,需要导入符合某JSON Schema的数据。该Schema的作者将部分枚举类型设计为由带const字符串属性的对象组成的anyOf数组,示例如下:

ApplicationType Schema片段

"ApplicationType": {
  "$id": "#ApplicationType",
  "anyOf": [
    {
      "additionalProperties": false,
      "properties": {
        "description": {
          "const": "Consent to make small (minor material) changes to a project with Planning Permission",
          "type": "string"
        },
        "value": {
          "const": "amendment.minorMaterial",
          "type": "string"
        }
      },
      "required": [
        "value",
        "description"
      ],
      "type": "object"
    },
    {
      "additionalProperties": false,
      "properties": {
        "description": {
          "const": "Consent to make small (non-material) changes to a project with Planning Permission",
          "type": "string"
        },
        "value": {
          "const": "amendment.nonMaterial",
          "type": "string"
        }
      },
      "required": [
        "value",
        "description"
      ],
      "type": "object"
    }
  ]
}

FileType Schema片段

"FileType": {
  "$id": "#FileType",
  "anyOf": [
    {
      "additionalProperties": false,
      "properties": {
        "description": {
          "const": "Elevations - existing",
          "type": "string"
        },
        "value": {
          "const": "elevations.existing",
          "type": "string"
        }
      },
      "required": [
        "value",
        "description"
      ],
      "type": "object"
    },
    {
      "additionalProperties": false,
      "properties": {
        "description": {
          "const": "Elevations - proposed",
          "type": "string"
        },
        "value": {
          "const": "elevations.proposed",
          "type": "string"
        }
      },
      "required": [
        "value",
        "description"
      ],
      "type": "object"
    }
  ]
}

使用NJsonSchema导入这些结构时,生成的是带可写字符串属性的对象,没有保留原Schema中的const值。我希望能在代码中保留这些const值,用于数据验证和导入,目前尝试了三种方案但都不尽人意:


方案一:导入为枚举

将上述结构转换为带自定义特性的枚举类型:

enum EApplicationType
{
    [Code("amendment.minorMaterial")]
    ConsentToMakeSmallMinorMaterialChangesToAProjectWithPlanningPermission,
    [Code("amendment.nonMaterial")]
    ConsentToMakeSmallNonMaterialChangesToAProjectWithPlanningPermission,
}

enum EFileType
{
    [Code("elevations.existing")]
    ElevationsExisting,
    [Code("elevations.proposed")]
    ElevationsProposed,
}

优势:每个枚举有独立的类型约束;
不足:枚举与字符串值的转换、枚举项遍历都需要大量反射操作,虽可通过预加载字典规避,但增加了实现复杂度。


方案二:使用静态类+字符串属性

将const值封装为静态类的只读字符串属性:

static class ApplicationType
{
    public static string ConsentToMakeSmallMinorMaterialChangesToAProjectWithPlanningPermission => "amendment.minorMaterial";
    public static string ConsentToMakeSmallNonMaterialChangesToAProjectWithPlanningPermission => "amendment.nonMaterial";
}

static class FileType
{
    public static string ElevationsExisting => "elevations.existing";
    public static string ElevationsProposed => "elevations.proposed";
}

优势:实现简单,可直接通过字符串比较进行验证;
不足:没有类型约束(任意字符串都可传入),遍历所有可选值仍需反射。


方案三:使用类/实例对象

沿用原Schema的对象结构,定义对应类型或静态实例:

方式A:实现接口的类

public class ConsentToDisplayAnAdvertisement : IApplicationType
{
    public string Description => "ConsentToDisplayAnAdvertisement";
    public string Value => "advertConsent";

    public int CompareTo(object obj)
    {
        return Value.CompareTo((obj as IApplicationType).Value);
    }
}

方式B:静态类持有实例

public static class EEApplicationType
{
    public static DescriptionValue ConsentToMakeSmallChangesToAProjectWithPlanningPermission = new DescriptionValue
    (
        "ConsentToMakeSmallChangesToAProjectWithPlanningPermission",
        "amendment"
    );
}

优势:完全匹配原Schema的结构;
不足:对象实例无法直接用于switch语句,遍历所有可选值仍依赖反射。


请问是否有更优的实现方式?

内容的提问来源于stack exchange,提问作者Jamie Kitson

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 08:28:14