在.NET Core項目中也是可使用.resx資源文件,來爲程序提供多語言支持。如下咱們就以一個.NET Core控制檯項目爲例,來說解資源文件的使用。async
新建一個.NET Core控制檯項目,而後咱們在其中新建一個.resx資源文件叫DemoResource.resx測試
注意.resx資源文件默認是Internal訪問級別的,這會致使其它程序集沒法訪問資源文件類,因此咱們最好將其改成Public訪問級別spa
而後咱們在資源文件DemoResource.resx中定義一個字符串叫"Message",值爲"Hello",以下所示:線程
因爲資源文件是支持多語言的,其文件名命名格式以下:code
{資源文件名}.{語言文化名稱}.resx中間件
其中{語言文化名稱}就是諸如:zh-CN、en-US、ja-JP等語言字符串,表明了一種特定的語言,例如zh-CN就是簡體中文。blog
因此如今咱們就爲資源文件DemoResource.resx再創造兩種語言:ip
DemoResource.zh-CN.resx,簡體中文資源文件:資源
DemoResource.ja-JP.resx,日語資源文件:字符串
因此咱們如今,就有三個資源文件:
其實它們表明的都是DemoResource資源文件,只不過是不一樣的語言版本罷了,如今項目結構以下所示:
好了,如今定義好了資源文件,咱們就來看看怎麼使用它們。
在.NET Core中.resx資源文件是和線程的語言相關,其主要和當前線程的以下兩個語言屬性相關:
若是當前線程的這兩個屬性是什麼語言,那麼.resx資源文件就會返回對應語言的內容。
首先咱們在.NET Core控制檯項目的Main方法中,設置當前線程的CurrentCulture和CurrentUICulture爲zh-CN:
static void Main(string[] args) { Thread.CurrentThread.CurrentCulture = new CultureInfo("zh-CN"); Thread.CurrentThread.CurrentUICulture = new CultureInfo("zh-CN"); Console.WriteLine($"Message爲:{DemoResource.Message}"); Console.WriteLine("按任意鍵結束..."); Console.ReadKey(); }
運行結果以下,咱們能夠看到顯示的Message爲中文"你好"
如今咱們將當前線程的CurrentCulture和CurrentUICulture設置爲ja-JP:
static void Main(string[] args) { Thread.CurrentThread.CurrentCulture = new CultureInfo("ja-JP"); Thread.CurrentThread.CurrentUICulture = new CultureInfo("ja-JP"); Console.WriteLine($"Message爲:{DemoResource.Message}"); Console.WriteLine("按任意鍵結束..."); Console.ReadKey(); }
運行結果以下,咱們能夠看到顯示的Message爲日文"こんにちは"
而後,咱們將當前線程的CurrentCulture和CurrentUICulture設置爲fr-FR,表明法語:
static void Main(string[] args) { Thread.CurrentThread.CurrentCulture = new CultureInfo("fr-FR"); Thread.CurrentThread.CurrentUICulture = new CultureInfo("fr-FR"); Console.WriteLine($"Message爲:{DemoResource.Message}"); Console.WriteLine("按任意鍵結束..."); Console.ReadKey(); }
那麼如今結果是什麼呢,以下所示:
可能不少同窗會以爲很奇怪爲何Message顯示的是英語"Hello"。其實道理很簡單,由於咱們沒有定義DemoResource.fr-FR.resx這個法語資源文件啊,因此在當前線程的CurrentCulture和CurrentUICulture爲fr-FR時,調用DemoResource.Message時,.NET Core只好使用DemoResource默認資源文件DemoResource.resx的內容,因此DemoResource.Message輸出的是英文"Hello"。
其實資源文件類DemoResource也是能夠經過設置其Culture屬性來指定使用某一種特定的語言,以下代碼所示,雖然咱們設置當前線程的CurrentCulture和CurrentUICulture爲ja-JP,可是因爲咱們設置了DemoResource.Culture爲zh-CN:
static void Main(string[] args) { Thread.CurrentThread.CurrentCulture = new CultureInfo("ja-JP"); Thread.CurrentThread.CurrentUICulture = new CultureInfo("ja-JP"); DemoResource.Culture = new CultureInfo("zh-CN"); Console.WriteLine($"Message爲:{DemoResource.Message}"); Console.WriteLine("按任意鍵結束..."); Console.ReadKey(); }
因此最後顯示的Message爲中文"你好"
Async和Await模式對線程語言的影響
有的同窗可能會想.NET Core中的Async和Await模式,會對Thread.CurrentThread.CurrentCulture和Thread.CurrentThread.CurrentUICulture這兩個線程的語言屬性產生影響嗎。
咱們來看看以下代碼:
/// <summary> /// 測試Async和Await模式,是否會對Thread.CurrentThread.CurrentCulture和Thread.CurrentThread.CurrentUICulture產生影響 /// </summary> static void AsyncAwaitThreadCulture() { //設置主線程的CurrentCulture和CurrentUICulture爲語言ja-JP Thread.CurrentThread.CurrentCulture = new CultureInfo("ja-JP"); Thread.CurrentThread.CurrentUICulture = new CultureInfo("ja-JP"); Console.WriteLine($"Thread id:{Thread.CurrentThread.ManagedThreadId.ToString()}=>主線程的CurrentCulture是{Thread.CurrentThread.CurrentCulture.ToString()}, CurrentUICulture是{Thread.CurrentThread.CurrentUICulture.ToString()}"); //經過Task來啓動第一層線程 Task.Run(async () => { Console.WriteLine($"Thread id:{Thread.CurrentThread.ManagedThreadId.ToString()}=>第一層線程的CurrentCulture是{Thread.CurrentThread.CurrentCulture.ToString()}, CurrentUICulture是{Thread.CurrentThread.CurrentUICulture.ToString()}"); //經過Task來啓動第二層線程 Task task = Task.Run(() => { Console.WriteLine($"Thread id:{Thread.CurrentThread.ManagedThreadId.ToString()}=>第二層線程的CurrentCulture是{Thread.CurrentThread.CurrentCulture.ToString()}, CurrentUICulture是{Thread.CurrentThread.CurrentUICulture.ToString()}"); //經過Thread來啓動第三層線程 Thread th = new Thread(new ThreadStart(() => { Thread.Sleep(3000); Console.WriteLine($"Thread id:{Thread.CurrentThread.ManagedThreadId.ToString()}=>第三層線程的CurrentCulture是{Thread.CurrentThread.CurrentCulture.ToString()}, CurrentUICulture是{Thread.CurrentThread.CurrentUICulture.ToString()}"); })); th.IsBackground = true; th.Start(); th.Join();//阻塞第二層線程,直到第三層線程th結束 }); Thread.Sleep(1000); Console.WriteLine($"Thread id:{Thread.CurrentThread.ManagedThreadId.ToString()}=>await以前CurrentCulture是{Thread.CurrentThread.CurrentCulture.ToString()}, CurrentUICulture是{Thread.CurrentThread.CurrentUICulture.ToString()}"); await task;//await,直到第二層線程結束 Console.WriteLine($"Thread id:{Thread.CurrentThread.ManagedThreadId.ToString()}=>await以後CurrentCulture是{Thread.CurrentThread.CurrentCulture.ToString()}, CurrentUICulture是{Thread.CurrentThread.CurrentUICulture.ToString()}"); }).Wait();//阻塞主線程,直到第一層線程執行完畢 }
運行結果以下所示:
咱們在AsyncAwaitThreadCulture方法中,將主線程的CurrentCulture和CurrentUICulture設置爲了ja-JP,結果能夠發現後續啓動的線程其CurrentCulture和CurrentUICulture也都爲ja-JP
如今咱們設置主線程的CurrentCulture和CurrentUICulture爲ja-JP,可是將第一層線程的CurrentCulture和CurrentUICulture改成zh-CN
/// <summary> /// 測試Async和Await模式,是否會對Thread.CurrentThread.CurrentCulture和Thread.CurrentThread.CurrentUICulture產生影響 /// </summary> static void AsyncAwaitThreadCulture() { //設置主線程的CurrentCulture和CurrentUICulture爲語言ja-JP Thread.CurrentThread.CurrentCulture = new CultureInfo("ja-JP"); Thread.CurrentThread.CurrentUICulture = new CultureInfo("ja-JP"); Console.WriteLine($"Thread id:{Thread.CurrentThread.ManagedThreadId.ToString()}=>主線程的CurrentCulture是{Thread.CurrentThread.CurrentCulture.ToString()}, CurrentUICulture是{Thread.CurrentThread.CurrentUICulture.ToString()}"); //經過Task來啓動第一層線程 Task.Run(async () => { //將第一層線程的CurrentCulture和CurrentUICulture改成zh-CN Thread.CurrentThread.CurrentCulture = new CultureInfo("zh-CN"); Thread.CurrentThread.CurrentUICulture = new CultureInfo("zh-CN"); Console.WriteLine($"Thread id:{Thread.CurrentThread.ManagedThreadId.ToString()}=>第一層線程的CurrentCulture是{Thread.CurrentThread.CurrentCulture.ToString()}, CurrentUICulture是{Thread.CurrentThread.CurrentUICulture.ToString()}"); //經過Task來啓動第二層線程 Task task = Task.Run(() => { Console.WriteLine($"Thread id:{Thread.CurrentThread.ManagedThreadId.ToString()}=>第二層線程的CurrentCulture是{Thread.CurrentThread.CurrentCulture.ToString()}, CurrentUICulture是{Thread.CurrentThread.CurrentUICulture.ToString()}"); //經過Thread來啓動第三層線程 Thread th = new Thread(new ThreadStart(() => { Thread.Sleep(3000); Console.WriteLine($"Thread id:{Thread.CurrentThread.ManagedThreadId.ToString()}=>第三層線程的CurrentCulture是{Thread.CurrentThread.CurrentCulture.ToString()}, CurrentUICulture是{Thread.CurrentThread.CurrentUICulture.ToString()}"); })); th.IsBackground = true; th.Start(); th.Join();//阻塞第二層線程,直到第三層線程th結束 }); Thread.Sleep(1000); Console.WriteLine($"Thread id:{Thread.CurrentThread.ManagedThreadId.ToString()}=>await以前CurrentCulture是{Thread.CurrentThread.CurrentCulture.ToString()}, CurrentUICulture是{Thread.CurrentThread.CurrentUICulture.ToString()}"); await task;//await,直到第二層線程結束 Console.WriteLine($"Thread id:{Thread.CurrentThread.ManagedThreadId.ToString()}=>await以後CurrentCulture是{Thread.CurrentThread.CurrentCulture.ToString()}, CurrentUICulture是{Thread.CurrentThread.CurrentUICulture.ToString()}"); }).Wait();//阻塞主線程,直到第一層線程執行完畢 }
如今運行結果以下:
咱們能夠看到從第一層線程開始,後續啓動線程的CurrentCulture和CurrentUICulture都爲zh-CN了
這說明在.NET Core中,默認狀況下線程的CurrentCulture和CurrentUICulture屬性是由啓動它的線程來決定的,上面的結果很明顯因爲第一層線程的CurrentCulture和CurrentUICulture爲zh-CN,因此由第一層線程啓動的後續線程(第二層和第三層線程)也都爲zh-CN。因此在.NET Core中要設置線程的CurrentCulture和CurrentUICulture屬性,最簡單的辦法就是在根線程(主線程)上設置CurrentCulture和CurrentUICulture的語言便可。
最後若是是在ASP.NET Core中,只須要寫一箇中間件(Middleware),來更改主線程的CurrentCulture和CurrentUICulture屬性爲特定語言,便可實現.resx資源文件的全局利用,固然ASP.NET Core中也有一套自帶的資源文件匹配規則,這裏你們以爲怎麼用起來方便怎麼用便可。