TL;DR
- C#はECMA-334仕様でUnicode識別子を正式サポート。日本語プロパティ名はビルドエラーにならない
-
{Binding 名前}形式のXAMLバインディングは正常に動作する(WPFはリフレクションでプロパティ名を解決) -
nameof(名前)もコンパイル時に"名前"に変換され、INotifyPropertyChangedと組み合わせて安全に使える - JSONシリアライズは
[JsonPropertyName]属性で英語キーとのマッピングが可能 - 実用上の課題はIME切り替えコスト・英語サンプルとの乖離・チーム規約の問題
環境
| 項目 | バージョン・詳細 |
|---|---|
| OS | Windows 11 |
| .NET | .NET 8以上 |
| C# | 12以上 |
| WPF | .NET 8 WPF |
| IDE | Visual Studio 2022 |
C#のUnicode識別子サポート
C# 言語仕様(ECMA-334)の識別子定義はUnicode Letterカテゴリを含む。漢字・ひらがな・カタカナはUnicode Letterに該当するため、プロパティ名・変数名・クラス名に使える。
// 正式に有効なC#コード
public class 利用者
{
public string 名前 { get; set; }
public int 年齢 { get; set; }
public string メールアドレス { get; set; }
}
Visual Studio 2022のIntelliSenseも日本語識別子を認識し、補完候補に表示する。
WPFデータバインディングでの動作
ViewModelの実装
using System.ComponentModel;
public class 利用者ViewModel : INotifyPropertyChanged
{
private string _名前;
public string 名前
{
get => _名前;
set
{
_名前 = value;
OnPropertyChanged(nameof(名前)); // 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));
}
nameof(名前) はコンパイル時に文字列定数 "名前" に変換される。プロパティ名を文字列でハードコードするよりリファクタリング耐性が高い。
XAMLの実装
<Window x:Class="JapanesePropDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:JapanesePropDemo"
Title="日本語バインディング検証">
<Window.DataContext>
<local:利用者ViewModel />
</Window.DataContext>
<StackPanel Margin="20">
<Label Content="名前" />
<TextBox Text="{Binding 名前, UpdateSourceTrigger=PropertyChanged}" />
<Label Content="年齢" />
<TextBox Text="{Binding 年齢, UpdateSourceTrigger=PropertyChanged}" />
<TextBlock Text="{Binding 名前}" FontSize="16" Margin="0,10,0,0" />
</StackPanel>
</Window>
{Binding 名前} は正常にバインドされる。WPFのバインディングエンジンはリフレクションでDataContextのプロパティを名前解決しているため、Unicode文字列のプロパティ名も問題なく処理される。
DataContext設定(code-behind方式の場合)
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new 利用者ViewModel
{
名前 = "テストユーザー",
年齢 = 30
};
}
}
JSONシリアライズとのマッピング
REST APIのレスポンス(英語キー)を日本語プロパティのクラスにデシリアライズする場合、[JsonPropertyName] 属性でマッピングできる。
System.Text.Json
using System.Text.Json.Serialization;
public class 利用者
{
[JsonPropertyName("name")]
public string 名前 { get; set; }
[JsonPropertyName("age")]
public int 年齢 { get; set; }
[JsonPropertyName("email")]
public string メールアドレス { get; set; }
}
// デシリアライズ
var json = """{"name":"田中太郎","age":30,"email":"tanaka@example.com"}""";
var 利用者データ = JsonSerializer.Deserialize<利用者>(json);
Console.WriteLine(利用者データ.名前); // → 田中太郎
// シリアライズ(英語キーで出力される)
var result = JsonSerializer.Serialize(利用者データ);
// → {"name":"田中太郎","age":30,"email":"tanaka@example.com"}
Newtonsoft.Json
using Newtonsoft.Json;
public class 利用者
{
[JsonProperty("name")]
public string 名前 { get; set; }
[JsonProperty("age")]
public int 年齢 { get; set; }
}
ハマりどころ・注意点
IME切り替えコスト
英語キーワード(public・string・get・set)と日本語プロパティ名の間で頻繁にIMEを切り替える必要がある。入力ミスでひらがなのまま英語部分を書いてしまうことが起きる。
バックスラッシュ・記号入力との競合
日本語IMEがオンの状態で { や } を入力すると、環境によって全角文字として入力されることがある。特にXAMLを手書きするときは注意が必要。
英語コミュニティのサンプルとの乖離
StackOverflowやMicrosoft Learn公式サンプルはすべて英語識別子。コピーしてそのまま使えないため、変数名の読み替えが常に発生する。
リフレクションを使うライブラリとの相性
AutoMapper・EF Core・Doxygenなどのツールは英語識別子を前提に設計されていることが多い。日本語プロパティ名でも動作するが、マッピング定義や規約が複雑になるケースがある。
ソースコードのエンコーディング
.csファイルと.xamlファイルはUTF-8で保存する。BOMなしUTF-8(UTF-8 without BOM)が.NETの推奨。Visual Studio 2022はデフォルトでUTF-8を使うため通常は問題ないが、古いエディタを混在させると文字化けが発生することがある。
使用が適する場面・避ける場面
| 場面 | 判断 |
|---|---|
| 一人開発の社内ツール | アリ。日本語ドメイン用語が仕様書と一致する利点がある |
| 日本語ドメインが強いビジネスロジック | 検討の余地あり。英訳でニュアンスが失われるケース |
| チーム開発 | 原則避ける。英語ベースの規約と混在するとコスト増 |
| OSS・外部公開コード | 避ける。日本語が読めない開発者が参加できない |
| REST API連携が多い実装 | 避ける。属性マッピングの手間が増える |
まとめ
-
{Binding 名前}はWPFで正常に動作する。技術的な制約は存在しない -
nameof(日本語プロパティ名)は安全に使え、INotifyPropertyChangedと組み合わせても問題なし - JSONシリアライズは
[JsonPropertyName]で英語キーとのマッピングが可能 - 採用する場合はファイル全体で識別子言語を統一する。英語と日本語の混在が最も読みにくい
- チーム規約・外部連携・将来の拡張性を踏まえた判断が必要
概要や実際に試してみた感想も含めた記事はこちら → C# WPFのデータバインディングで日本語プロパティ名を使ったら何が起きるか