// Caller should acquire a lock before calling the method.

        // static
        public static FontLanguages getById(uint id)
        {
            FontLanguageListCache inst = FontLanguageListCache.getInstance();

            LOG_ALWAYS_FATAL_IF(id >= inst.mLanguageLists.Count, "Lookup by unknown language list ID.");
            return(inst.mLanguageLists[id]);
        }
        // Returns language list ID for the given string representation of
        // FontLanguages. Caller should acquire a lock before calling the method.

        // static
        public static uint getId(string languages)
        {
            FontLanguageListCache inst = FontLanguageListCache.getInstance();

            Dictionary <string, uint> .Enumerator it = inst.mLanguageListLookupTable.find(languages);
//C++ TO C# CONVERTER TODO TASK: Iterators are only converted within the context of 'while' and 'for' loops:
            if (it != inst.mLanguageListLookupTable.end())
            {
//C++ TO C# CONVERTER TODO TASK: Iterators are only converted within the context of 'while' and 'for' loops:
                return(it.second);
            }

            // Given language list is not in cache. Insert it and return newly assigned
            // ID.
            uint          nextId        = inst.mLanguageLists.Count;
            FontLanguages fontLanguages = new FontLanguages(minikin.GlobalMembers.parseLanguageList(languages));

            if (fontLanguages.empty())
            {
                return(kEmptyListId);
            }
            inst.mLanguageLists.Add(std::move(fontLanguages));
            inst.mLanguageListLookupTable.Add(languages, nextId);
            return(nextId);
        }