有没有一种好的、可读的方法来在 C# 中定义简单的嵌套 类

Is there a good, readable way to define simple nested classes in C#

我是一位经验丰富的 C# 软件工程师。我已经阅读了文档并浏览了博客。我怀疑答案是“不,C# 不支持”,但在这里值得一问:

假设我有这样一个 JSON 数据描述:

{
  "data": {
    "name": {
      "first_name": "Fred",
      "last_name": Smith,
    },
    "address": {
      "street": "123 Main Street",
      "city": "Anytown",
      "state": "CA"
    }
}

JSON 使得创建深度嵌套的数据结构变得非常容易。但是为了在 C# 中表示相同的数据结构,我显然需要为每个嵌套结构定义一个单独的 class,如下所示:

private class Data {
  public Name name { get; set; }
  public Address address { get; set; }
}

private class name {
  public string first_name { get; set; }
  public string last_name { get; set; }
}

private class Address {
  public string street { get; set; }
  public string city { get; set; }
  public string state { get; set; }
}

是否有任何方法可以简化此代码以接近 JSON 表示的简单性?

你混淆了两个不同的概念。您包含的 JSON 定义了 对象 。使用匿名类型的 C# 等效项可能如下所示:

new
{
    data = new
    {
        name = new
        {
            first_name = "Fred",
            last_name = "Smith"
        },
        address = new
        {
            street = "123 Main Street",
            city = "Anytown",
            state = "CA"
        }
    }
}

您发布的 C# 代码定义了 类型 。因为 JavaScript 还没有类型,所以必须用 TypeScript 这样的语言来完成与此等效的操作。打字稿看起来像这样:

type response = {
  data: {
    name: {
      first_name: string,
      last_name: string
    },
    address: {
      street: string,
      city: string,
      state: string
    }
  }
}

没有像这样声明嵌套 C# 类型的简单语法。您 可以 声明 C# 类 嵌套在其他 类 中,但这不允许您像 TypeScript 那样声明与 属性 名称内联的类型确实。

如果您尝试在 C# 中使用 consume JSON,并且不关心像上面的 C# 代码那样创建强类型,您可以完全避免创建类型: 只需将 JSON 反序列化为 dynamic 类型,或使用 JToken 之类的类型并使用字符串访问其片段。 (有关如何执行此操作的详细信息将取决于您的序列化框架。)

如果您希望构建更易于阅读的新类型,只需使用记事本 ++ 之类的东西并先制作一个 json 对象,然后使用转换工具自动将其制作成 C# 对象。

这是另一种方式: 您可以做的是查看从 C#

生成 Avro 模式

如果您希望使流程自动化,您可以执行以下操作 https://www.thecodebuzz.com/generate-avro-schema-from-json/

如果class之间相互依赖性很强,例如nameaddresssdata之外没有意义,你可以定义它们在 data 内,嵌套 classes。你不保存代码,反而更加封装。

在那种情况下,你这样做:

private class Data
{
    public Name name { get; set; }
    public Address address { get; set; }

    #region Nested classes

    public class Name
    {
        public string first_name { get; set; }
        public string last_name { get; set; }
    }

    public class Address
    {
        public string street { get; set; }
        public string city { get; set; }
        public string state { get; set; }
    }

    #endregion
}

有了这个区域,您可以折叠该代码并让您的 Data class 减轻过载。