Help us understand the problem. What is going on with this article?

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

前提

  • 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;
}
Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away