Repository: dotnet/aspnetcore
File: src/Components/WebAssembly/WebAssembly/src/Hosting/WebAssemblyCultureProvider.cs (C#)

Code before:
        }

        var culturesToLoad = GetCultures(CultureInfo.CurrentCulture, CultureInfo.CurrentUICulture);

        if (culturesToLoad.Length == 0)
        {
            return;
        }

        await WebAssemblyCultureProviderInterop.LoadSatelliteAssemblies(culturesToLoad);
    }

    internal static string[] GetCultures(CultureInfo? cultureInfo, CultureInfo? uiCultureInfo = null)
    {
        var culturesToLoad = new List<string>();

        // Once WASM is ready, we have to use .NET's assembly loading to load additional assemblies.
        // First calculate all possible cultures that the application might want to load. We do this by
        // starting from the current culture and walking up the graph of parents.
        // At the end of the the walk, we'll have a list of culture names that look like
        // [ "fr-FR", "fr" ]
        while (cultureInfo != null || uiCultureInfo != null)
        {
            if (cultureInfo != null && cultureInfo != CultureInfo.InvariantCulture)
            {
                culturesToLoad.Add(cultureInfo.Name);
            }

            if (uiCultureInfo != null && uiCultureInfo.Name != cultureInfo?.Name && uiCultureInfo != CultureInfo.InvariantCulture)
            {
                culturesToLoad.Add(uiCultureInfo.Name);
            }

            cultureInfo = (cultureInfo?.Parent == cultureInfo || cultureInfo == CultureInfo.InvariantCulture) ? null : cultureInfo?.Parent;
            uiCultureInfo = (uiCultureInfo?.Parent == uiCultureInfo || uiCultureInfo == CultureInfo.InvariantCulture) ? null : uiCultureInfo?.Parent;
        }

        return culturesToLoad.ToArray();
    }

    private partial class WebAssemblyCultureProviderInterop
    {
        [JSImport("INTERNAL.loadSatelliteAssemblies")]
        public static partial Task LoadSatelliteAssemblies(string[] culturesToLoad);
    }
}


Review comment (refactor):
The logic doesn't prevent duplicate culture names from being added to the list. If `cultureInfo` and `uiCultureInfo` have the same parent cultures, duplicates could be added. Consider using a HashSet or checking for duplicates before adding.

Code after:
            throw new PlatformNotSupportedException("This method is only supported in the browser.");
        }

        var culturesToLoad = GetCultures(CultureInfo.CurrentCulture, CultureInfo.CurrentUICulture);

        if (culturesToLoad.Length == 0)
        {
            return;
        }

        await WebAssemblyCultureProviderInterop.LoadSatelliteAssemblies(culturesToLoad);
    }

    internal static string[] GetCultures(CultureInfo cultureInfo, CultureInfo? uiCultureInfo = null)
    {
        // Once WASM is ready, we have to use .NET's assembly loading to load additional assemblies.
        // First calculate all possible cultures that the application might want to load. We do this by
        // starting from the current culture and walking up the graph of parents.
        // At the end of the the walk, we'll have a list of culture names that look like
        // [ "fr-FR", "fr" ]

        var culturesToLoad = GetCultureHierarchy(cultureInfo);
        if (cultureInfo != uiCultureInfo)
        {
            foreach (var culture in GetCultureHierarchy(uiCultureInfo))
            {
                if (!culturesToLoad.Contains(culture))
                {
                    culturesToLoad = culturesToLoad.Append(culture);
                }
                // If the culture is in the list, we can break because we found the common parent.
                else
                {
                    break;
                }
            }
        }

        return culturesToLoad.ToArray();
    }

    private static IEnumerable<string> GetCultureHierarchy(CultureInfo? culture)
    {
        while (culture != CultureInfo.InvariantCulture && culture != null)
        {
            yield return culture.Name;
            if (culture == culture.Parent)
            {
                break;
            }
            culture = culture.Parent;