C# - 声明和初始化嵌套数组

C# - Declaring and initializing a nested array

问题:我需要创建一个带有字符串键的集合,它有两个字段,其中包含一个字符串键数组。这将在 .cs 文件的 namespace 部分内的多个函数中引用,而不仅仅是在单个函数或 class 中引用。除了初始化之外,它里面的数据不会改变。

在Lua中,这是非常琐碎且容易做到的。像这样:

local tableCulturesToRaceGender = {};

tableCulturesToRaceGender["Northern Empire"] = { 
    male={
        "EmpireMale",
        "BattaniaMale",
        "KhuzaitMale"},
    female = {
        "EmpireFemale"
        }
    }

--[[
--Visual layout of the nested array
tableCulturesToRaceGender["Northern Empire"]
    male
        [1] = "EmpireMale"
        [2] = "BattaniaMale"
        [3] = "KhuzaitMale"
    female
        [1] = "EmpireFemale"
--]]

local function UseTheTable()

    local strEntry = tableCulturesToRaceGender["Northern Empire"].male[2]
    --StrEntry is now filled with: BattaniaMale

end

我费了好大劲才弄清楚这个问题。各种警告、样板、{get; set;} 苦差事、getter 和 setter 函数、关于可变性的东西、你怎么不能 readonly list<> 等。然后是范围;将列表放入命名空间无法完成,将其放入 class 由于可变性等原因不起作用

这是一个过于复杂的混乱局面,其中包含许多专为已经知道一切含义的人准备的行话。我已经在这几个小时了,我比刚开始时更困惑。

那么,我该怎么做呢?

为您的数据使用 classes 和通用容器。您可以初始化一个 class,这样客户端就不能使用 private fields 更改只能被 get 编辑而不能被 public property 编辑的数据(即C# 行话,如果你想使用 C#,你必须学习它---抱歉)。您可以使用一个接口,以便不同的 'empires' 具有相同类型的数据但具有不同的值(如果需要,还有更多可选内容)。这是一种在 C# 中非常惯用的方法:

using System;
using System.Collections.Generic;

namespace Culture
{
    public interface IRaces
    {
        public string Empire { get; }
        public List<string> Male { get; }
        public List<string> Female { get; }
    }
    public class NorthernEmpire : IRaces
    {
        private readonly string _empire = "Northern";
        public string Empire => _empire;
        private readonly List<string> _male = new() { "Empire", "Battania", "Khuzait" };
        public List<string> Male => _male;
        private readonly List<string> _female = new() { "Empire" };
        public List<string> Female => _female;
        private readonly string _fightingStyle = "whatever";
        public string FightingStyle => _fightingStyle;

    }
    public class SouthernEmpire : IRaces
    {
        private readonly string _empire = "Southern";
        public string Empire => _empire;
        private readonly List<string> _male = new() { "Empire" };
        public List<string> Male => _male;
        private readonly List<string> _female = new() { "Empire", "Battania", "Khuzait" };
        public List<string> Female => _female;

    }
    internal class Program
    {
        static void Main()
        {
            List<IRaces> raceList = new();
            raceList.Add(new NorthernEmpire());
            raceList.Add(new SouthernEmpire());
            foreach (IRaces races in raceList)
            {
                Console.WriteLine($"Empire: {races.Empire}:");
                foreach (string maleRace in races.Male)
                    Console.WriteLine($"\tMale race: {maleRace}");
                foreach (string femaleRace in races.Female)
                    Console.WriteLine($"\tFemale race: {femaleRace}");
                if (races is NorthernEmpire)
                    Console.WriteLine($"\tFighting Style: {((NorthernEmpire)races).FightingStyle}");
            }
        }
    }
}

输出:

Empire: Northern:
        Male race: Empire
        Male race: Battania
        Male race: Khuzait
        Female race: Empire
        Fighting Style: whatever
Empire: Southern:
        Male race: Empire
        Female race: Empire
        Female race: Battania
        Female race: Khuzait

你的 Lua 代码的一个字对字的翻译应该是这样的:

var tableCulturesToRaceGender = new
{
    northernEmpire = new
    { 
        male = new[]
        {
            "EmpireMale",
            "BattaniaMale",
            "KhuzaitMale"
        },
        female = new[]
        {
            "EmpireFemale"
        }
    }
};

var result = tableCulturesToRaceGender.northernEmpire.male[0];

I'm having a hell of a time figuring this out. All sort of caveats, boilerplate, {get; set;} drudgery, getter and setter functions, stuff about mutability, how you can't readonly list<>, etc. And then there's the scope; putting a list in a namespace cannot be done, putting it in a class doesn't work due to mutability, etc.

小心那个咆哮,它只表明你没有费心阅读任何文档。整段话你一个字都没说,更不用说下一段了。

您是否考虑过在 C# 中使用 Enumerations? 在您的集合中,添加一个 get-only 属性 并将下面的枚举作为输出类型。 枚举不是可变的,因为它们实际上是常量。 如果你愿意,你也可以用自定义属性装饰每个条目。

enum MaleEntries
{
    EmpireMale = 1,
    BattaniaMale = 2,
    KhuzaitMale = 3
}

enum FemaleEntries
{
    EmpireFemale = 1
}