.NET(C#):CultureInfo中重要的InvariantCulture

目录

  • CultureInfo简述
  • 通过示例了解InvariantCulture
  • InvariantCulture和字符串比较
  • 总结

返回目录

CultureInfo简述

CultureInfo类位于System.Globalization命名空间内,这个类和这个命名空间许多人都不了解也认为不需要太多了解,实际上,你写的程序中会经常间接得使用这些类。

简单的说:当进行数字,日期时间,字符串匹配时,都会进行CultureInfo的操作,也就是不同的CultureInfo下,这些操作的结果可能会不一样。这里要介绍一下非常容易被忽视的InvariantCulture。

返回目录

通过示例了解InvariantCulture

前面提到过,不同的CultureInfo会影响某些函数的执行结果,.NET中有一个特殊的CultureInfo:InvariantCulture,这个CultureInfo有点像英语格式,但它不和国家地区挂钩,它可以提供一个可靠的在多语言环境下的规范格式化。

比如你编写一个程序,要向数据中心服务器传递一些时间数据,你会怎么写?直接DateTime.ToString()?那你就大错特错了,下面用代码,举个非常形象的例子。在一个控制台里,模拟数据中心,然后放出多个线程,模拟客户端程序传递数据。

static readonly string[] CultureSources = { "en-us", "zh-cn", "ar-iq", "de-de" };

static readonly Random Ran = new Random(Environment.TickCount);

static void Main()

{

Console.WriteLine("数据中心开始接受客户端数据:");

for (int i = 0; i < CultureSources.Length; i++)

ThreadPool.QueueUserWorkItem(Client, i);

Console.ReadKey(true);

Console.WriteLine("");

Console.WriteLine("数据中心:…………");

}

static void Client(object obj)

{

int id = (int)obj;

Thread.Sleep(Ran.Next(1000));

CultureInfo cul = CultureInfo.GetCultureInfo(CultureSources[id]);

Thread.CurrentThread.CurrentCulture = cul;

Console.WriteLine("某客户端操作系统语言设置{0}\n传送数据:{1}\n", cul.DisplayName, new DateTime(1990, 10,27).ToShortDateString());

}

运行结果:

结果看到了吧,同样的DateTime.ToShortDateString(),在英语-美国,中文-中国,阿拉伯语-伊拉克和德语-德国的不同环境下,1990年10月27日竟然有如此不同的输出结果,这些数据让数据中心服务器情何以堪啊……

原因则已提到过,在进行日期时间输出时,.NET会考虑当前线程的CultureInfo,即Thread.CurrentThread.CurrentCulture(或者CultureInfo.CurrentCulture),并根据CultureInfo,进行相应地区文化的数据处理。注意不要和UICulture混淆。

解决方案就是使用这个特殊的InvariantCulture。

把输出代码改成

Console.WriteLine("某客户端操作系统语言设置{0}\n传送数据:{1}\n", cul.DisplayName,

new DateTime(1990, 10, 27).ToString(

CultureInfo.InvariantCulture.DateTimeFormat.ShortDatePattern, CultureInfo.InvariantCulture));

这样不管客户端运行在什么语言环境下,输出的时间格式都是统一的,方面数据中心服务器对数据做后续处理。

(当然这个例子仅用来演示InvariantCulture的用法,是否存在其他不妥处这里不做讨论)

返回目录

InvariantCulture和字符串比较

下面代码进行四种字符串比较方法,分别是zh-cn, en-us文化,数值比较和InvariantCulture比较(全部是区分大小写)。

static void Main()

{

string[] strs =

{ "a", "A", "b", "B", "abc", "ab", "aB", "AB", "Ab", "aaa", "00", "0001", "002", "a4", "a9","a33" };

Console.WriteLine("en-US");

Array.Sort<string>(strs, StringComparer.Create(CultureInfo.GetCultureInfo("en-us"), false));

Console.WriteLine(String.Join(" < ", strs));

Console.WriteLine("zh-CN");

Array.Sort<string>(strs, StringComparer.Create(CultureInfo.GetCultureInfo("zh-CN"), false));

Console.WriteLine(String.Join(" < ", strs));

Console.WriteLine("Ordinal");

Array.Sort<string>(strs, StringComparer.Ordinal);

Console.WriteLine(String.Join(" < ", strs));

Console.WriteLine("Invariant");

Array.Sort<string>(strs, StringComparer.InvariantCulture);

Console.WriteLine(String.Join(" < ", strs));

}

比较结果

en-US

00 < 0001 < 002 < a < A < a33 < a4 < a9 < aaa < ab < aB < Ab < AB < abc < b < B

zh-CN

00 < 0001 < 002 < a < A < a33 < a4 < a9 < aaa < ab < aB < Ab < AB < abc < b < B

Ordinal

00 < 0001 < 002 < A < AB < Ab < B < a < a33 < a4 < a9 < aB < aaa < ab < abc < b

Invariant

00 < 0001 < 002 < a < A < a33 < a4 < a9 < aaa < ab < aB < Ab < AB < abc < b < B

(下面全部是区分大小写)

Ordinal是传统比较方式,即比较每个字符的数值,如果相等的话,继续比较下一组,如果有一个没有的话,长度大的算大。

Invariant和大多数CultureInfo都用一种更人性化的比较方法。首先判断一组字符是否是不一样(这里不区分大小写),直接返回结果如果不一样,因此b>AB,B>abc。如果一样的话比较下一组,如果都一样则比较长度,所以abc>AB>ab,如果长度都一样最后再比较大小写,另外一个字符大写永远大于小写,所以AB>Ab>aB>ab

更新:

那么InvariantCulture这样比较字符串有什么作用呢?我觉得这样输出形式可读性更高,其实InvariantCulture比较字符串就是先进行一次不区分大小写的Ordinal比较(不过这里大写字母>小写字母),如果结果不相同的话在进行一遍区分大小写的Ordinal比较(同样这里也是大写字母>小写字母)。这样可以将字符串先进行一次大的筛选,然后再比较细节,看下面的示例,Ordinal和InvariantCulture的比较结果可读性更高!

string[] arr = { "Ab", "aB", "AB", "ab", "Abccccccc", "aBccccc", "Abd" };

Array.Sort<string>(arr, StringComparer.Ordinal);

Console.WriteLine(String.Join("\n", arr));

Console.WriteLine();

Array.Sort<string>(arr, StringComparer.InvariantCulture);

Console.WriteLine(String.Join("\n", arr));

比较结果:

Ordinal InvariantCulture
AB 
Ab 
Abccccccc 
Abd 
aB 
aBccccc 
ab
ab 
aB 
Ab 
AB 
aBccccc 
Abccccccc 
Abd

结果显而易见,Ordinal机器式的纯数值比较,上面的Ordinal排序结果看起来还是很乱,而InvariantCulture则可读性更高。

返回目录

总结

支持多种CultureInfo是整个.NET Framework更加人性化,因为这可以使同一个数据适应不同地区和文化,这样当然满足处于不同地区和文化的用户,但前提是数据给“人”看,如果这些数据用于计算机之间的传输,即给“机器”看,这样的多文化处理反而不妥,造成同一个数据的不同展现形式,尤其是读写两方的文化地区不同时,数据可能根本无法被正常读取或者产生潜在bug,因此这里,正是InvariantCulture的用武之地。

.NET(C#):ToString(CultureInfo.InvariantCulture)相关推荐

  1. System.Globalization.CultureInfo.InvariantCulture 解决不同地域字符串格式不同问题

    同样的DateTime.ToShortDateString()   在不同的地域输出格式不同 如在美国的 日期格式为 :  月-日-年 如在中国的 日期格式为 :  年-月-日 一些时候,这个格式就会 ...

  2. C# CultureInfo.InvariantCulture

    今天在写代码的过程中发现了一个有意思的问题,我在写了一个日期格式转化的时候发现不同电脑的运行结果不一致. 代码如下 string str = this.tbTime.Text;if(string.Is ...

  3. JavaScript函数补完:toString()

    javascript中的toString()方法,主要用于Array.Boolean.Date.Error.Function.Number等对象.下面是这些方法的一些解析和简单应用,做个纪律,以作备忘 ...

  4. System.Globalization.CultureInfo.InvariantCulture失效

    dataset ds; ds.Locale = System.Globalization.CultureInfo.InvariantCulture;  //失效就用下面的  System.Thread ...

  5. 头条三面:toString()、String.valueOf、(String)强转,有啥区别?

    欢迎关注方志朋的博客,回复"666"获面试宝典 一.前言 相信大家在日常开发中这三种方法用到的应该很多,尤其是前两种,经常在开发的时候,随心所欲,想用哪个用哪个,既然存在,那就应该 ...

  6. 在日期格式化的时候提示错误:Tostring没有采用一个参数的重载

    这个问题主要是要把这个参数先转换为日期,然后才能用tostring去格式化 具体做法如下: <%# Convert.ToDateTime(Eval("A_TIME")).To ...

  7. c# 扩展方法奇思妙用高级篇五:ToString(string format) 扩展

    在.Net中,System.Object.ToString()是用得最多的方法之一,ToString()方法在Object类中被定义为virtual,Object类给了它一个默认实现: 1     p ...

  8. 【转】CultureInfo中重要的InvariantCulture

    原贴地址:http://www.soaspx.com/dotnet/csharp/csharp_20110506_7607.html CultureInfo简述 CultureInfo类位于Syste ...

  9. CultureInfo中重要的InvariantCulture

    CultureInfo简述 CultureInfo类位于System.Globalization命名空间内,这个类和这个命名空间许多人都不了解也认为不需要太多了解,实际上,你写的程序中会经常间接得使用 ...

最新文章

  1. php -- PDO事务处理
  2. tableau实战系列(七)-服务器日志清理和级别设置
  3. Matlab中凸优化工具包CVX的配置、注册与使用
  4. 流行病学与生物统计学: 临床研究导论 Epidemiology and Biostatistics: An Introduction to Clinical Research
  5. js 判断是否是IE浏览器及ie版本
  6. html 滚动条停止事件,CSS scroll-snap滚动事件停止及元素位置检测实现
  7. [Swift]LeetCode884. 两句话中的不常见单词 | Uncommon Words from Two Sentences
  8. python中的画布控制_使按钮在画布上工作(tkinter)
  9. (软件工程复习核心重点)第二章可行性研究-第一节:可行性研究基本介绍
  10. 相机内参中cx cy_Opencv中的两种去畸变函数
  11. 优秀程序员应该具备的 11 个特质
  12. SpringCloud常见面试题总结一
  13. 速率法和终点法的区别_终点法 速率法 二点法
  14. 温度、水汽压、湿度计算公式
  15. logging日志带颜色
  16. hdu(杭电oj)第一页题目题解
  17. 支持多种视频格式的html网页视频播放器代码
  18. TOEFL wordlist 14
  19. 2021-03-04 mysql in里加个参数就查不到??是JSON_EXTRACT导致的,用JSON_UNQUOTE()去掉双引号就正常了
  20. 难得五年来第一次暑假没有出海,即使最终没有逃过8月份的CPT外业

热门文章

  1. 苹果iOS系统下检查第三方APP是否安装
  2. Window截图方法
  3. 火山引擎 A/B 测试私有化实践
  4. 开源sso单点登陆系统推荐
  5. lv双肩包尺寸对照表_这10个最火的LV双肩包,我就是不要好好背!
  6. 宇道生物完成复星医药Pre-A轮融资,专注药物研发信息化和智能化开发...
  7. 基于Activiti的流程应用开发平台JSAAS-WF V5.3
  8. wi-fi_Google语音正在测试Wi-Fi呼叫,无需呼叫转移
  9. 微信扫描二维码调用手机外部浏览器打开下载apk的链接
  10. Android应用安全检测工具简介