LoginSignup
0
0

More than 3 years have passed since last update.

UnityEngineのデフォルト言語 `default (SystemLanguage)` は アフリカン

Last updated at Posted at 2019-09-21

前提

  • unity 2018.4.9f1

困ったこと、やりたいこと

  • default (SystemLanguage)は、SystemLanguage.Afrikaansで、SystemLanguage.Unknownではありません。
  • Unknownを含む全てのSystemLanguage値と区別可能な「Undef」をdefault値に持つ、SystemLanguageの拡張型が欲しいです。

試したこと

継承して拡張する

  • SystemLanguageは列挙型なので継承できませんでした。

Null許容型を流用する

  • SystemLanguage?を使って、nullを未定義とみなすようにしてみました。
  • 諸々の不具合が生じて断念しました。

新しい型を作る

  • 上記のNullable<T>での失敗から、Booleanable<Language>という概念を考えてみました。

解決策

  • 論理値も持つLanguage構造体を作ってみたところ、取り敢えず使えそうです。

特徴

  • デフォルト値はLanguage.Undefです。
    • Language lang = default;とすると、langにはLanguage.Undefが入ります。
    • 構造体なので、未初期化のままで使用することはできません。
  • Language.Undefは、SystemLanguageに対してSystemLanguage.Unknownとして振る舞います。
    • SystemLanguage syslang = lang;とすると、syslangにはSystemLanguage.Unknownが入ります。
  • SystemLanguageと互換性があり、相互に代入や比較(暗黙の型変換)が可能です。
    • Language lang = SystemLanguage.Japanese;ができます。
    • SystemLanguage syslang = lang;ができます。
    • if (lang == SystemLanguage.Japanese) { }ができます。
  • 論理値を持ちます。
    • if (lang) { }のような論理値コンテキストでは、Language.Undef以外なら真になります。
    • lang = Language.Undef;と、lang = false;は同じ結果です。
  • 文字列型と相互に変換が可能です。
    • ToString ()ができます。
    • Enum準拠で、Language.Parse (), Language.TryParse ()ができます。
      • SystemLanguageに存在しない名前は、全てLanguage.Undefになります。
  • Nullable<T>に似た実装です。(たぶん)
    • GetValueOrDefault ()ができます。

コード

BooleanableSystemLanguage.cs
using System;
using UnityEngine;

public struct Language : IEquatable<Language> {
    private bool hasValue;
    private SystemLanguage language;
    public static readonly Language Undef = new Language (false);
    public Language (bool _hasValue) {
        hasValue = _hasValue;
        language = _hasValue ? Application.systemLanguage : SystemLanguage.Unknown;
    }
    public Language (SystemLanguage _language) {
        hasValue = _language != SystemLanguage.Unknown;
        language = _language;
    }
    public static bool TryParse (string name, bool ignoreCase, out Language language) {
        if (string.IsNullOrEmpty (name) || !Enum.TryParse (name, ignoreCase, out SystemLanguage syslang)) {
            language = Undef;
            return false;
        }
        language = syslang;
        return true;
    }
    public static bool TryParse (string name, out Language language) => TryParse (name, false, out language);
    public static Language Parse (string name, bool ignoreCase) { TryParse (name, ignoreCase, out var language); return language; }
    public static Language Parse (string name) { TryParse (name, false, out var language); return language; }
    public SystemLanguage GetValueOrDefault () => hasValue ? language : SystemLanguage.Unknown;
    public SystemLanguage GetValueOrDefault (Language l) => hasValue ? language : (SystemLanguage) l;
    public static implicit operator bool (Language l) => l.hasValue;
    public static implicit operator SystemLanguage (Language l) => l.hasValue ? l.language : SystemLanguage.Unknown;
    public static implicit operator Language (bool b) => new Language (b);
    public static implicit operator Language (SystemLanguage l) => new Language (l);
    public override string ToString () => hasValue ? language.ToString () : "Undef";
    public static bool operator == (Language a, Language b) => (a.hasValue == b.hasValue) && (!a.hasValue || a.language == b.language);
    public static bool operator != (Language a, Language b) => !(a == b);
    public bool Equals (Language other) => (hasValue == other.hasValue) && (language == other.language);
    public override bool Equals (object obj) => (obj == null || GetType () != obj.GetType ()) ? false : Equals ((Language) obj);
    public override int GetHashCode () => hasValue ? language.GetHashCode () : int.MinValue;
}
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0