C# WPFのデータバインディングで日本語プロパティ名を使ったら何が起きるか
「C#って日本語の変数名が使えるらしい」という話は聞いたことがあった。でも実際にWPFのデータバインディングで試したことはなかった。{Binding 名前}みたいに書いて本当に動くのか。動いたとして、実用に耐えるのか。半分好奇心、半分「どうせ落とし穴があるだろう」という気持ちで検証してみた。
そもそもC#は日本語識別子を正式にサポートしている
C#の言語仕様(ECMA-334)では、識別子にUnicode文字を使えると明記されている。つまり変数名・プロパティ名・クラス名に漢字・ひらがな・カタカナをそのまま使えるのは仕様として保証された挙動で、バグでも裏技でもない。
// これは正式に有効なC#コード
public class 利用者
{
public string 名前 { get; set; }
public int 年齢 { get; set; }
public string メールアドレス { get; set; }
}
Visual Studio 2022でも普通にIntelliSenseが効く。補完候補に「名前」「年齢」が出てくる様子はなかなかシュールだけど、ビルドは通る。
WPFのXAMLバインディングでも使えるか
ViewModelに日本語プロパティを持たせてXAMLからバインドしてみた。
// ViewModel
public class 利用者ViewModel : INotifyPropertyChanged
{
private string _名前;
public string 名前
{
get => _名前;
set
{
_名前 = value;
OnPropertyChanged(nameof(名前));
}
}
private int _年齢;
public int 年齢
{
get => _年齢;
set
{
_年齢 = value;
OnPropertyChanged(nameof(年齢));
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string name)
=> PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
<!-- XAML -->
<StackPanel>
<TextBox Text="{Binding 名前, UpdateSourceTrigger=PropertyChanged}" />
<TextBox Text="{Binding 年齢, UpdateSourceTrigger=PropertyChanged}" />
<TextBlock Text="{Binding 名前}" />
</StackPanel>
結果は——動く。{Binding 名前}でちゃんとViewModelの名前プロパティにバインドされて、TextBoxに入力した値がリアルタイムで反映される。WPFのバインディングは内部でリフレクションを使ってプロパティ名を文字列で解決しているので、Unicode名でも問題ない。
nameof()も日本語プロパティで機能する
INotifyPropertyChangedの実装でnameof(名前)と書けるのが地味に重要で、プロパティ名のタイポをコンパイル時に検出できる。ハードコードで"名前"と文字列を渡す実装より安全だ。
// nameof()は日本語プロパティでも正しく機能する
OnPropertyChanged(nameof(名前)); // → "名前" という文字列になる
実際に困った点
IME切り替えのストレス
コードを書くとき、英字と日本語の間で頻繁にIMEを切り替えることになる。public string まで英字で書いて、プロパティ名を入力するために日本語入力に切り替えて、また { get; set; }に戻す、という繰り返しが思ったより煩わしい。慣れの問題かもしれないけど、英語コードの中に日本語が挟まるリズムが崩れる感覚は否めない。
バックエンドとの連携がつらい
APIのレスポンスをViewModelにマッピングするとき、JSONのキーは英語("name"、"age")でプロパティは日本語、という状況になる。System.Text.JsonやNewtonsoft.Jsonで属性を付ければ対応できるけど、一段階手間が増える。
using System.Text.Json.Serialization;
public class 利用者
{
[JsonPropertyName("name")]
public string 名前 { get; set; }
[JsonPropertyName("age")]
public int 年齢 { get; set; }
}
StackOverflowやGitHub Copilotとの相性
英語のプロパティ名なら、同じ構造のコードがStackOverflowにいくらでもある。日本語プロパティ名のコードは検索してもほぼ出てこないし、Copilotの補完も精度が落ちる。サンプルコードをそのまま流用しにくい。
使ってみた正直な感想
「動く」と「実用的」は別の話だと改めて思った。一人で書く小さなツールで、日本語のビジネスドメインを扱う場合は選択肢としてアリかもしれない。「顧客番号」「請求金額」「納期」みたいな用語が英訳すると意味が曖昧になるドメインでは、日本語のまま書いた方がコードと仕様書の対応がはっきりする、という考え方はわかる。
ただチームで使う場合や、外部のAPIやライブラリとの連携が多い場合は苦労の方が大きいと思う。英語識別子のコードベースに日本語が混ざると、どちらのルールで書けばいいか迷う人が出てくる。「愚行」と言い切るほどではないけど、採用するなら明確な理由と運用ルールが必要だ。
まとめ
- C#は仕様としてUnicode識別子をサポートしており、日本語プロパティ名は正式に有効
- WPFのデータバインディング(
{Binding 名前}形式)も日本語プロパティで正常に動作する nameof()・INotifyPropertyChanged・XAMLバインディングすべて問題なく機能した- 実用上の課題はIME切り替え、JSON属性の追加、英語サンプルコードとの乖離
- ドメイン用語が日本語で完結する一人プロジェクトなら選択肢になりうる。チーム開発では要検討