我有这段代码,当我尝试获取不存在的文化时,会抛出异常。
是否存在像TryGetCultureInfo
这样返回bool
值的方法?我不想使用try-catch
语句。
CultureInfo culture = CultureInfo.GetCultureInfo(cultureCode);
if (culture == null)
{
culture = CultureInfo.GetCultureInfo(DefaultCultureCode);
}
我有这段代码,当我尝试获取不存在的文化时,会抛出异常。
是否存在像TryGetCultureInfo
这样返回bool
值的方法?我不想使用try-catch
语句。
CultureInfo culture = CultureInfo.GetCultureInfo(cultureCode);
if (culture == null)
{
culture = CultureInfo.GetCultureInfo(DefaultCultureCode);
}
您可以编写一个返回布尔值的DoesCultureExist方法,就像这样:
private static bool DoesCultureExist(string cultureName)
{
return CultureInfo.GetCultures(CultureTypes.AllCultures).Any(culture => string.Equals(culture.Name, cultureName, StringComparison.CurrentCultureIgnoreCase));
}
CultureInfo
通常的工作方式。 - Crono我认为没有这样的方法。因此,您可以只使用try-catch
或检查所有已安装的区域设置:
string cultureCode = "de-DE";
CultureInfo[] cultures = CultureInfo.GetCultures(CultureTypes.AllCultures & ~CultureTypes.NeutralCultures);
var culture = cultures.FirstOrDefault(c => c.Name.Equals(cultureCode, StringComparison.OrdinalIgnoreCase));
if (culture == null)
{
culture = cultures.FirstOrDefault(c => c.Name.Equals(DefaultCultureCode, StringComparison.OrdinalIgnoreCase));
if (culture == null)
culture = CultureInfo.CurrentCulture;
}
但我更喜欢 try-catch
,我相信它更有效率。
public bool TryGetCultureInfo(string cultureCode, string DefaultCultureCode, out CultureInfo culture)
{
try
{
culture = CultureInfo.GetCultureInfo(cultureCode);
return true;
} catch(CultureNotFoundException)
{
if (DefaultCultureCode == null)
culture = CultureInfo.CurrentCulture;
else
{
try
{
culture = CultureInfo.GetCultureInfo(DefaultCultureCode);
} catch (CultureNotFoundException)
{
culture = CultureInfo.CurrentCulture;
}
}
}
return false;
}
CultureNotFoundException
异常,所以类型很重要。还有许多其他可能出现的异常,比如 ArgumentNullException
或者 OutOfMemoryException
,你可能不想在这里捕获它们。另外,如果你不给参数命名,就没有人会认为你在使用该异常 —— catch (CultureNotFoundException) { culture = CultureInfo.CurrentCulture; }
。这展示了你准确的目的以及你期望发生的情况。 - Aidan RyanCultureNotFoundException
;) 好的,我明白了,已经编辑了答案。谢谢。 - Tim SchmelterCultureInfo.GetCultureInfo("asd");
不会抛出异常。因此,这个答案是错误的! - Dominic Jonas如果想要速度更快,可以使用:
internal static class Culture
{
private static readonly HashSet<string> CultureNames = CreateCultureNames();
internal static bool Exists(string name)
{
return CultureNames.Contains(name);
}
private static HashSet<string> CreateCultureNames()
{
var cultureInfos = CultureInfo.GetCultures(CultureTypes.AllCultures)
.Where(x => !string.IsNullOrEmpty(x.Name))
.ToArray();
var allNames = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
allNames.UnionWith(cultureInfos.Select(x => x.TwoLetterISOLanguageName));
allNames.UnionWith(cultureInfos.Select(x => x.Name));
return allNames;
}
}
private static CultureInfo GetCulture(string name)
{
if (!CultureExists(name)) return null;
return CultureInfo.GetCultureInfo(name);
}
private static bool CultureExists(string name)
{
CultureInfo[] availableCultures =
CultureInfo.GetCultures(CultureTypes.AllCultures);
foreach (CultureInfo culture in availableCultures)
{
if (culture.Name.Equals(name))
return true;
}
return false;
}
希望这能有所帮助。
接受的答案速度较慢。你可以尝试另一种解决方案以获得更好的性能:在try-catch语句中使用CultureInfo.GetCultureInfo
。
尽管try-catch通常不是一个好主意,但我仍建议在catch CultureNotFoundException
子句中使用CultureInfo.GetCultureInfo
。
最重要的是,GetCultureInfo
具有线程安全的缓存的文化名称,因此每次调用时都不需要查找。
public static bool Exists(string name)
{
try
{
CultureInfo.GetCultureInfo(name);
return true;
}
catch (CultureNotFoundException)
{
return false;
}
}
我进行了一个基准测试,以检查哪种方法更快,而GetCultureInfo
明显(超过4000倍)更快。
结果:
BenchmarkDotNet v0.13.9+228a464e8be6c580ad9408e98f18813f6407fb5a, Windows 11 (10.0.22621.2506/22H2/2022Update/SunValley2)
12th Gen Intel Core i5-12400F, 1 CPU, 12 logical and 6 physical cores
.NET SDK 7.0.403
[Host] : .NET 7.0.13 (7.0.1323.51816), X64 RyuJIT AVX2
DefaultJob : .NET 7.0.13 (7.0.1323.51816), X64 RyuJIT AVX2
| Method | Mean | Error | StdDev |
|------------------------ |-------------:|-------------:|-------------:|
| GetCultureInfo_TryCatch | 19.88 ns | 0.372 ns | 0.330 ns |
| GetCultures | 83,831.36 ns | 1,638.645 ns | 2,599.065 ns |
[SimpleJob]
public class CultureExistsBenchmarks
{
[Benchmark]
public void GetCultureInfo_TryCatch()
{
try { CultureInfo.GetCultureInfo("zzz"); }
catch (CultureNotFoundException) { }
}
[Benchmark]
public void GetCultures() =>
CultureInfo.GetCultures(CultureTypes.AllCultures).Any(culture => string.Equals(culture.Name, "zzz", StringComparison.CurrentCultureIgnoreCase));
}
作为一种文化无关的替代方法,如果您不介意语言的方言,您可以构建一个包含ISO 639-2语言代码的字符串列表,并进行查找。