CultureInfo和ISO 639-3

时间:2014-01-10 10:37:42

标签: c# .net cultureinfo iso culture

我正在寻找一种从ISO 639-3语言代码构造CultureInfo对象的方法。我没有在MSDN中找到任何关于它的内容,并试图从所有文化列表中获取它不起作用...

CultureInfo cInfo = CultureInfo.GetCultures(CultureTypes.AllCultures)
                         .FirstOrDefault(r => String.Equals(r.ThreeLetterISOLanguageName, "CCH", StringComparison.CurrentCultureIgnoreCase));

将始终返回null(请注意,“CCH”是ISO-639-3列表中的一种语言)。

感谢任何想法,谢谢!

5 个答案:

答案 0 :(得分:7)

MSDN documentation表示CultureInfo对象只有ISO 639-2 three-letter codeISO 639-1 two-letter code。这意味着您需要某种映射才能将ISO 639-3代码链接到特定的CultureInfo实例。

This Wikipedia page包含映射表。也许您可以剪切并粘贴到XML文件中,并将其用作类库中的嵌入式资源,以便提供映射。或者甚至只是在某处定义静态Dictionary<string,string>

或者,我确信会有第三方图书馆可以为你做这件事(虽然我不知道有什么不在我的脑海里)。

编辑:

我没有意识到ISO 639-3代码只有有时会映射到ISO 639-2代码。这里的问题是CultureInfo类不是为了处理ISO 639-3规范而设计的,所以你可能必须找到一个完全不同的CultureInfo第三方实现来支持它 - 或者自己制作它。

答案 1 :(得分:2)

我发现自己需要ISO 639-3的枚举。如果你实际上不需要将它映射到CultureInfo,那么这可能会有所帮助:

http://snipplr.com/view/76196/enum-for-iso-6393-language-codes/

答案 2 :(得分:2)

我有类似的需要在ISO 639-2B / T和ISO 639-3格式之间进行转换。 我创建了一个TT4解决方案,在编译时生成所有7K +条目的列表。 我本可以使用字典而不是列表,但我正在搜索多个字段,因此价值不大。

http://www-01.sil.org/iso639-3/download.asp下载并解压缩制表符分隔的文本文件 将其复制到项目路径,根据需要重命名。

创建设计时模板文件:https://msdn.microsoft.com/en-us/library/dd820620.aspx

<#@ template debug="true" hostspecific="true" language="C#" #>
<#@ output extension=".cs" #>
<#@ assembly name="System.Core" #>
<#@ assembly name="Microsoft.VisualBasic.dll" #> 
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ import namespace="Microsoft.VisualBasic.FileIO" #>

// Generated code
using System.Collections.Generic;

namespace Foo
{
    // ISO 639-3
    // http://www-01.sil.org/iso639-3/download.asp
    public class ISO_639_3
    {
        // The three-letter 639-3 identifier
        public string Id { get; set; }
        // Equivalent 639-2 identifier of the bibliographic applications code set, if there is one
        public string Part2B { get; set; }
        // Equivalent 639-2 identifier of the terminology applications code set, if there is one
        public string Part2T { get; set; }
        // Equivalent 639-1 identifier, if there is one
        public string Part1 { get; set; }
        // I(ndividual), M(acrolanguage), S(pecial)
        public string Scope { get; set; }
        // A(ncient), C(onstructed), E(xtinct), H(istorical), L(iving), S(pecial)
        public string Language_Type { get; set; }
        // Reference language name
        public string Ref_Name { get; set; }
        // Comment relating to one or more of the columns
        public string Comment { get; set; }

        // Create a list of all known codes
        public static List<ISO_639_3> Create()
        {
            List<ISO_639_3> list = new List<ISO_639_3> {
<# 
    // Setup text parser
    string filename = this.Host.ResolvePath("iso-639-3.tab"); 
    TextFieldParser tfp = new TextFieldParser(filename)
    {
        TextFieldType = FieldType.Delimited,
        Delimiters = new[] { ",", "\t" },
        HasFieldsEnclosedInQuotes = true,
        TrimWhiteSpace = true
    };

    // Read first row as header
    string[] header = tfp.ReadFields();

    // Read rows from file
    // For debugging limit the row count
    //int maxrows = 10;
    int maxrows = int.MaxValue;
    int rowcount = 0;
    string term = "";
    while (!tfp.EndOfData && rowcount < maxrows)
    {
        // Read row of data from the file
        string[] row = tfp.ReadFields();
        rowcount ++;

        // Add "," on all but last line
        term = tfp.EndOfData || rowcount >= maxrows ? "" : ",";

        // Add new item from row data
#>
                new ISO_639_3 { Id = "<#=row[0]#>", Part2B = "<#=row[1]#>", Part2T = "<#=row[2]#>", Part1 = "<#=row[3]#>", Scope = "<#=row[4]#>", Language_Type = "<#=row[5]#>", Ref_Name = "<#=row[6]#>", Comment = "<#=row[7]#>" }<#=term#>
<# 
    } 
#>  
            };
            return list;
        }

    }

}

生成的代码将为包含所有语言的列表创建初始化程序。 这个文件很大,它会降低编辑速度,编译需要很长时间,除非你需要,否则保持卸载。 片段:

public static List<ISO_639_3> Create()
{
    List<ISO_639_3> list = new List<ISO_639_3> {
        new ISO_639_3 { Id = "aaa", Part2B = "", Part2T = "", Part1 = "", Scope = "I", Language_Type = "L", Ref_Name = "Ghotuo", Comment = "" },
        new ISO_639_3 { Id = "aab", Part2B = "", Part2T = "", Part1 = "", Scope = "I", Language_Type = "L", Ref_Name = "Alumu-Tesu", Comment = "" },
        new ISO_639_3 { Id = "aac", Part2B = "", Part2T = "", Part1 = "", Scope = "I", Language_Type = "L", Ref_Name = "Ari", Comment = "" },

使用生成的列表根据需要进行映射,例如

    public static ISO_639_3 GetISO_639_3(string language)
    {
        // Create list if it does not exist
        if (Program.Default.ISO6393List == null)
        {
            Program.Default.ISO6393List = ISO_639_3.Create();
        }

        // Match the input string type
        ISO_639_3 lang = null;
        if (language.Length > 3 && language.ElementAt(2) == '-')
        {
            // Treat the language as a culture form, e.g. en-us
            CultureInfo cix = new CultureInfo(language);

            // Recursively call using the ISO 639-2 code
            return GetISO_639_3(cix.ThreeLetterISOLanguageName);
        }
        else if (language.Length > 3)
        {
            // Try long form
            lang = Program.Default.ISO6393List.Where(item => item.Ref_Name.Equals(language, StringComparison.OrdinalIgnoreCase)).FirstOrDefault();
            if (lang != null)
                return lang;
        }
        else if (language.Length == 3)
        {

            // Try 639-3
            lang = Program.Default.ISO6393List.Where(item => item.Id.Equals(language, StringComparison.OrdinalIgnoreCase)).FirstOrDefault();
            if (lang != null)
                return lang;

            // Try the 639-2/B
            lang = Program.Default.ISO6393List.Where(item => item.Part2B.Equals(language, StringComparison.OrdinalIgnoreCase)).FirstOrDefault();
            if (lang != null)
                return lang;

            // Try the 639-2/T
            lang = Program.Default.ISO6393List.Where(item => item.Part2T.Equals(language, StringComparison.OrdinalIgnoreCase)).FirstOrDefault();
            if (lang != null)
                return lang;
        }
        else if (language.Length == 2)
        {
            // Try 639-1
            lang = Program.Default.ISO6393List.Where(item => item.Part1.Equals(language, StringComparison.OrdinalIgnoreCase)).FirstOrDefault();
            if (lang != null)
                return lang;
        }

        // Not found
        return lang;
    }

答案 3 :(得分:1)

请查看C#的文本模板。 (* .TT)

它允许您在项目中重新保存文件时生成文件:

<#@import namespace="System.Globalization"#>
<#@ output extension=".cs" #>
namespace YourProject.Enum
{
    enum eLanguage
    {
        Unknown,
        <#
        CultureInfo[] cultures = CultureInfo.GetCultures(CultureTypes.AllCultures);
        foreach (var culture in cultures) { #>
        <#= culture.TwoLetterISOLanguageName #>
        <#
        }
        #>
        Other
    }
}

答案 4 :(得分:0)

这里是类固醇的枚举

namespace System.Globalization
{
    using System.Collections.Generic;
    public enum SpokenLang
    {

        [Spoken.Lang("Afaraf", "aa", "aar")]
        Afar,
        [Spoken.Lang("Аҧсуа", "ab", "abk")]
        Abkhazian,
        [Spoken.Lang("Afrikaans", "af", "afr")]
        Afrikaans,
        [Spoken.Lang("Akan", "ak", "aka")]
        Akan,
        [Spoken.Lang("አማርኛ", "am", "amh")]
        Amharic,
        [Spoken.Lang("‫العربية", "ar", "ara")]
        Arabic,
        [Spoken.Lang("Aragonés", "an", "arg")]
        Aragonese,
        [Spoken.Lang("অসমীয়া", "as", "asm")]
        Assamese,
        [Spoken.Lang("авар мацӀ", "av", "ava")]
        Avaric,
        [Spoken.Lang("Avestan", "ae", "ave")]
        Avestan,
        [Spoken.Lang("Aymar aru", "ay", "aym")]
        Aymara,
        [Spoken.Lang("Azərbaycan dili", "az", "aze")]
        Azerbaijani,
        [Spoken.Lang("башҡорт теле", "ba", "bak")]
        Bashkir,
        [Spoken.Lang("Bamanankan", "bm", "bam")]
        Bambara,
        [Spoken.Lang("Беларуская", "be", "bel")]
        Belarusian,
        [Spoken.Lang("বাংলা", "bn", "ben")]
        Bengali,
        [Spoken.Lang("Bislama", "bi", "bis")]
        Bislama,
        [Spoken.Lang("བོད་ཡིག", "bo", "bod")]
        Tibetan,
        [Spoken.Lang("Bosanski jezik", "bs", "bos")]
        Bosnian,
        [Spoken.Lang("Brezhoneg", "br", "bre")]
        Breton,
        [Spoken.Lang("български език", "bg", "bul")]
        Bulgarian,
        [Spoken.Lang("Català", "ca", "cat")]
        Catalan,
        [Spoken.Lang("Česky", "cs", "ces")]
        Czech,
        [Spoken.Lang("Chamoru", "ch", "cha")]
        Chamorro,
        [Spoken.Lang("нохчийн мотт", "ce", "che")]
        Chechen,
        [Spoken.Lang("Словѣньскъ", "cu", "chu")]
        ChurchSlavic,
        [Spoken.Lang("чӑваш чӗлхи", "cv", "chv")]
        Chuvash,
        [Spoken.Lang("Kernewek", "kw", "cor")]
        Cornish,
        [Spoken.Lang("Corsu", "co", "cos")]
        Corsican,
        [Spoken.Lang("ᓀᐦᐃᔭᐍᐏᐣ", "cr", "cre")]
        Cree,
        [Spoken.Lang("Cymraeg", "cy", "cym")]
        Welsh,
        [Spoken.Lang("Dansk", "da", "dan")]
        Danish,
        [Spoken.Lang("Deutsch", "de", "deu")]
        German,
        [Spoken.Lang("‫ދިވެހި", "dv", "div")]
        Dhivehi,
        [Spoken.Lang("རྫོང་ཁ", "dz", "dzo")]
        Dzongkha,
        [Spoken.Lang("Ελληνικά", "el", "ell")]
        ModernGreek,
        [Spoken.Lang("English", "en", "eng")]
        English,
        [Spoken.Lang("Esperanto", "eo", "epo")]
        Esperanto,
        [Spoken.Lang("Eesti keel", "et", "est")]
        Estonian,
        [Spoken.Lang("Euskara", "eu", "eus")]
        Basque,
        [Spoken.Lang("Ɛʋɛgbɛ", "ee", "ewe")]
        Ewe,
        [Spoken.Lang("Føroyskt", "fo", "fao")]
        Faroese,
        [Spoken.Lang("‫فارسی", "fa", "fas")]
        Persian,
        [Spoken.Lang("Vosa Vakaviti", "fj", "fij")]
        Fijian,
        [Spoken.Lang("Suomen kieli", "fi", "fin")]
        Finnish,
        [Spoken.Lang("Français", "fr", "fra")]
        French,
        [Spoken.Lang("Frysk", "fy", "fry")]
        WesternFrisian,
        [Spoken.Lang("Fulfulde", "ff", "ful")]
        Fulah,
        [Spoken.Lang("Gàidhlig", "gd", "gla")]
        ScottishGaelic,
        [Spoken.Lang("Gaeilge", "ga", "gle")]
        Irish,
        [Spoken.Lang("Galego", "gl", "glg")]
        Galician,
        [Spoken.Lang("Ghaelg", "gv", "glv")]
        Manx,
        [Spoken.Lang("Avañe'ẽ", "gn", "grn")]
        Guarani,
        [Spoken.Lang("ગુજરાતી", "gu", "guj")]
        Gujarati,
        [Spoken.Lang("Kreyòl ayisyen", "ht", "hat")]
        Haitian,
        [Spoken.Lang("‫هَوُسَ", "ha", "hau")]
        Hausa,
        [Spoken.Lang("Serbo-Croatian", "sh", "hbs")]
        SerboCroatian,
        [Spoken.Lang("‫עברית", "he", "heb")]
        Hebrew,
        [Spoken.Lang("Otjiherero", "hz", "her")]
        Herero,
        [Spoken.Lang("हिन्दी", "hi", "hin")]
        Hindi,
        [Spoken.Lang("Hiri Motu", "ho", "hmo")]
        HiriMotu,
        [Spoken.Lang("Hrvatski", "hr", "hrv")]
        Croatian,
        [Spoken.Lang("magyar", "hu", "hun")]
        Hungarian,
        [Spoken.Lang("Հայերեն", "hy", "hye")]
        Armenian,
        [Spoken.Lang("Igbo", "ig", "ibo")]
        Igbo,
        [Spoken.Lang("Ido", "io", "ido")]
        Ido,
        [Spoken.Lang("ꆇꉙ", "ii", "iii")]
        SichuanYi,
        [Spoken.Lang("ᐃᓄᒃᑎᑐᑦ", "iu", "iku")]
        Inuktitut,
        [Spoken.Lang("Interlingue", "ie", "ile")]
        Interlingue,
        [Spoken.Lang("Interlingua", "ia", "ina")]
        Interlingua,
        [Spoken.Lang("Bahasa Indonesia", "id", "ind")]
        Indonesian,
        [Spoken.Lang("Iñupiaq", "ik", "ipk")]
        Inupiaq,
        [Spoken.Lang("Íslenska", "is", "isl")]
        Icelandic,
        [Spoken.Lang("Italiano", "it", "ita")]
        Italian,
        [Spoken.Lang("Basa Jawa", "jv", "jav")]
        Javanese,
        [Spoken.Lang("日本語", "ja", "jpn")]
        Japanese,
        [Spoken.Lang("Kalaallisut", "kl", "kal")]
        Kalaallisut,
        [Spoken.Lang("ಕನ್ನಡ", "kn", "kan")]
        Kannada,
        [Spoken.Lang("कश्मीरी", "ks", "kas")]
        Kashmiri,
        [Spoken.Lang("ქართული", "ka", "kat")]
        Georgian,
        [Spoken.Lang("Kanuri", "kr", "kau")]
        Kanuri,
        [Spoken.Lang("Қазақ тілі", "kk", "kaz")]
        Kazakh,
        [Spoken.Lang("ភាសាខ្មែរ", "km", "khm")]
        Khmer,
        [Spoken.Lang("Gĩkũyũ", "ki", "kik")]
        Kikuyu,
        [Spoken.Lang("Kinyarwanda", "rw", "kin")]
        Kinyarwanda,
        [Spoken.Lang("кыргыз тили", "ky", "kir")]
        Kirghiz,
        [Spoken.Lang("коми кыв", "kv", "kom")]
        Komi,
        [Spoken.Lang("KiKongo", "kg", "kon")]
        Kongo,
        [Spoken.Lang("한국어", "ko", "kor")]
        Korean,
        [Spoken.Lang("Kuanyama", "kj", "kua")]
        Kuanyama,
        [Spoken.Lang("Kurdî", "ku", "kur")]
        Kurdish,
        [Spoken.Lang("ພາສາລາວ", "lo", "lao")]
        Lao,
        [Spoken.Lang("Latine", "la", "lat")]
        Latin,
        [Spoken.Lang("Latviešu valoda", "lv", "lav")]
        Latvian,
        [Spoken.Lang("Limburgs", "li", "lim")]
        Limburgan,
        [Spoken.Lang("Lingála", "ln", "lin")]
        Lingala,
        [Spoken.Lang("Lietuvių kalba", "lt", "lit")]
        Lithuanian,
        [Spoken.Lang("Lëtzebuergesch", "lb", "ltz")]
        Luxembourgish,
        [Spoken.Lang("kiluba", "lu", "lub")]
        LubaKatanga,
        [Spoken.Lang("Luganda", "lg", "lug")]
        Ganda,
        [Spoken.Lang("Kajin M̧ajeļ", "mh", "mah")]
        Marshallese,
        [Spoken.Lang("മലയാളം", "ml", "mal")]
        Malayalam,
        [Spoken.Lang("मराठी", "mr", "mar")]
        Marathi,
        [Spoken.Lang("македонски јазик", "mk", "mkd")]
        Macedonian,
        [Spoken.Lang("Fiteny malagasy", "mg", "mlg")]
        Malagasy,
        [Spoken.Lang("Malti", "mt", "mlt")]
        Maltese,
        [Spoken.Lang("Монгол", "mn", "mon")]
        Mongolian,
        [Spoken.Lang("Te reo Māori", "mi", "mri")]
        Maori,
        [Spoken.Lang("Bahasa Melayu", "ms", "msa")]
        Malay,
        [Spoken.Lang("ဗမာစာ", "my", "mya")]
        Burmese,
        [Spoken.Lang("Ekakairũ Naoero", "na", "nau")]
        Nauru,
        [Spoken.Lang("Diné bizaad", "nv", "nav")]
        Navajo,
        [Spoken.Lang("Ndébélé", "nr", "nbl")]
        SouthNdebele,
        [Spoken.Lang("isiNdebele", "nd", "nde")]
        NorthNdebele,
        [Spoken.Lang("Owambo", "ng", "ndo")]
        Ndonga,
        [Spoken.Lang("नेपाली", "ne", "nep")]
        Nepali,
        [Spoken.Lang("Nederlands", "nl", "nld")]
        Dutch,
        [Spoken.Lang("Norsk nynorsk", "nn", "nno")]
        NorwegianNynorsk,
        [Spoken.Lang("Norsk bokmål", "nb", "nob")]
        NorwegianBokmål,
        [Spoken.Lang("Norsk", "no", "nor")]
        Norwegian,
        [Spoken.Lang("ChiCheŵa", "ny", "nya")]
        Nyanja,
        [Spoken.Lang("Occitan", "oc", "oci")]
        Occitan,
        [Spoken.Lang("ᐊᓂᔑᓈᐯᒧᐎᓐ", "oj", "oji")]
        Ojibwa,
        [Spoken.Lang("ଓଡ଼ିଆ", "or", "ori")]
        Oriya,
        [Spoken.Lang("Afaan Oromoo", "om", "orm")]
        Oromo,
        [Spoken.Lang("Ирон ӕвзаг", "os", "oss")]
        Ossetian,
        [Spoken.Lang("ਪੰਜਾਬੀ", "pa", "pan")]
        Panjabi,
        [Spoken.Lang("पािऴ", "pi", "pli")]
        Pali,
        [Spoken.Lang("Polski", "pl", "pol")]
        Polish,
        [Spoken.Lang("Português", "pt", "por")]
        Portuguese,
        [Spoken.Lang("‫پښتو", "ps", "pus")]
        Pushto,
        [Spoken.Lang("Runa Simi", "qu", "que")]
        Quechua,
        [Spoken.Lang("Rumantsch grischun", "rm", "roh")]
        Romansh,
        [Spoken.Lang("Română", "ro", "ron")]
        Romanian,
        [Spoken.Lang("kiRundi", "rn", "run")]
        Rundi,
        [Spoken.Lang("русский язык", "ru", "rus")]
        Russian,
        [Spoken.Lang("Yângâ tî sängö", "sg", "sag")]
        Sango,
        [Spoken.Lang("संस्कृतम्", "sa", "san")]
        Sanskrit,
        [Spoken.Lang("සිංහල", "si", "sin")]
        Sinhala,
        [Spoken.Lang("Slovenčina", "sk", "slk")]
        Slovak,
        [Spoken.Lang("Slovenščina", "sl", "slv")]
        Slovenian,
        [Spoken.Lang("Davvisámegiella", "se", "sme")]
        NorthernSami,
        [Spoken.Lang("Gagana fa'a Samoa", "sm", "smo")]
        Samoan,
        [Spoken.Lang("chiShona", "sn", "sna")]
        Shona,
        [Spoken.Lang("सिन्धी", "sd", "snd")]
        Sindhi,
        [Spoken.Lang("Soomaaliga", "so", "som")]
        Somali,
        [Spoken.Lang("seSotho", "st", "sot")]
        SouthernSotho,
        [Spoken.Lang("Español", "es", "spa")]
        Spanish,
        [Spoken.Lang("Shqip", "sq", "sqi")]
        Albanian,
        [Spoken.Lang("sardu", "sc", "srd")]
        Sardinian,
        [Spoken.Lang("српски језик", "sr", "srp")]
        Serbian,
        [Spoken.Lang("SiSwati", "ss", "ssw")]
        Swati,
        [Spoken.Lang("Basa Sunda", "su", "sun")]
        Sundanese,
        [Spoken.Lang("Kiswahili", "sw", "swa")]
        Swahili,
        [Spoken.Lang("Svenska", "sv", "swe")]
        Swedish,
        [Spoken.Lang("Reo Mā`ohi", "ty", "tah")]
        Tahitian,
        [Spoken.Lang("தமிழ்", "ta", "tam")]
        Tamil,
        [Spoken.Lang("татарча", "tt", "tat")]
        Tatar,
        [Spoken.Lang("తెలుగు", "te", "tel")]
        Telugu,
        [Spoken.Lang("тоҷикӣ", "tg", "tgk")]
        Tajik,
        [Spoken.Lang("Tagalog", "tl", "tgl")]
        Tagalog,
        [Spoken.Lang("ไทย", "th", "tha")]
        Thai,
        [Spoken.Lang("ትግርኛ", "ti", "tir")]
        Tigrinya,
        [Spoken.Lang("faka Tonga", "to", "ton")]
        Tonga,
        [Spoken.Lang("seTswana", "tn", "tsn")]
        Tswana,
        [Spoken.Lang("xiTsonga", "ts", "tso")]
        Tsonga,
        [Spoken.Lang("Türkmen", "tk", "tuk")]
        Turkmen,
        [Spoken.Lang("Türkçe", "tr", "tur")]
        Turkish,
        [Spoken.Lang("Twi", "tw", "twi")]
        Twi,
        [Spoken.Lang("Uyƣurqə", "ug", "uig")]
        Uighur,
        [Spoken.Lang("українська мова", "uk", "ukr")]
        Ukrainian,
        [Spoken.Lang("‫اردو", "ur", "urd")]
        Urdu,
        [Spoken.Lang("O'zbek", "uz", "uzb")]
        Uzbek,
        [Spoken.Lang("tshiVenḓa", "ve", "ven")]
        Venda,
        [Spoken.Lang("Tiếng Việt", "vi", "vie")]
        Vietnamese,
        [Spoken.Lang("Volapük", "vo", "vol")]
        Volapük,
        [Spoken.Lang("Walon", "wa", "wln")]
        Walloon,
        [Spoken.Lang("Wollof", "wo", "wol")]
        Wolof,
        [Spoken.Lang("isiXhosa", "xh", "xho")]
        Xhosa,
        [Spoken.Lang("‫ייִדיש", "yi", "yid")]
        Yiddish,
        [Spoken.Lang("Yorùbá", "yo", "yor")]
        Yoruba,
        [Spoken.Lang("Saɯ cueŋƅ", "za", "zha")]
        Zhuang,
        [Spoken.Lang("中文", "zh", "zho")]
        Chinese,
        [Spoken.Lang("isiZulu", "zu", "zul")]
        Zulu,

    }


    public static class Spoken
    {
        public class LangAttribute : Attribute
        {
            public LangAttribute(string name, string iso639_1, string iso639_3)
            {
                NativeName = name;
                Iso639_1 = iso639_1;
                Iso639_3 = iso639_3;
            }
            public string Iso639_1 { get; }
            public string Iso639_3 { get; }
            public string NativeName { get; }

        }


        static readonly Dictionary<string, SpokenLang> isoMap = new Dictionary<string, SpokenLang>();
        static readonly Dictionary<SpokenLang, CultureInfo> langToCultureInfo = new Dictionary<SpokenLang, CultureInfo>();

        static Spoken()
        {

            foreach (SpokenLang lang in Enum.GetValues(typeof(SpokenLang)))
            {
                var langAttr = lang.GetLangAttribute();
                isoMap.Add(langAttr.Iso639_1, lang);
                isoMap.Add(langAttr.Iso639_3, lang);
                isoMap.Add(lang.ToString(), lang);
                isoMap.Add(langAttr.NativeName, lang);
            }
        }

        public static bool TryParseLanguageString(string str, out SpokenLang result)
       => isoMap.TryGetValue(str, out result);

        public static SpokenLang ParseLanguageString(string str)
        {
            if (!TryParseLanguageString(str, out var result))
                throw new ArgumentException($"unknown language string: {str}");

            return result;
        }

        public static LangAttribute GetLangAttribute(this SpokenLang enumVal)
        {
            var type = enumVal.GetType();
            var memInfo = type.GetMember(enumVal.ToString());
            var attributes = memInfo[0].GetCustomAttributes(typeof(LangAttribute), false);
            return (attributes.Length > 0) ? (LangAttribute)attributes[0] : null;
        }

        public static CultureInfo ToCultureInfo(this SpokenLang language) =>
         CultureInfo.GetCultureInfo(language.GetLangAttribute().Iso639_1);
    }
}

从@PieterV的t4模板构建