3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【WPF/MAUI】DependencyPropertyを1行で生成!ゼロアロケーションな爆速ジェネレーターを作った

3
Last updated at Posted at 2026-08-18

WPFやモダンなUIフレームワークを利用する上で避けて通れない依存関係プロパティ、すなわち DependencyProperty。強力な機能である反面、プロパティ一つ追加するだけで数十行に及ぶ冗長なボイラープレートコードを手書きする必要があり、ソースコードがカオスになる原因になっています。

「こんなコードは視界にも入れたくない!!」

ということでたった1行の属性で依存関係プロパティや添付プロパティを完全自動生成する、Source Generator「Kassyi.Generators.DependencyProperty」をリリースしました!

要約すると「小さいコンパイラを作った」のとほぼ同等です。

実は本プロジェクト、海外で非常に優れたジェネレーターを開発されている HavenDV 氏のプロジェクトをフォークし、そこからさらにゼロアロケーションによる圧倒的なパフォーマンスと、厳格な型安全にフォーカスして徹底的に魔改造を施したものになります。

リポジトリとNuGetはこちら👇ぜひスターをお願いします!
NuGet GitHub License

どんな特徴やこだわりがあるのか、サクッと紹介させてください!

1. 地獄のボイラープレートを「1行」で完全自動生成

[DependencyProperty<T>][AttachedDependencyProperty<T, TTarget>] をクラスに付与するだけで、裏側で必要な依存関係プロパティ・添付プロパティ・変更コールバックの登録処理をすべて自動で生成します。

【🙅‍♂️ Before】いつもの苦行

public static readonly DependencyProperty IsActiveProperty =
    DependencyProperty.Register(
        nameof(IsActive),
        typeof(bool),
        typeof(MyControl),
        new PropertyMetadata(false, OnIsActiveChanged));

public bool IsActive
{
    get => (bool)GetValue(IsActiveProperty);
    set => SetValue(IsActiveProperty, value);
}

private static void OnIsActiveChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    // キャストしてメソッド呼び出して...ああ面倒くさい...
}

【👍 After】Kassyi.Generators.DependencyProperty の場合

[DependencyProperty<bool>("IsActive", DefaultValue = "false")]
public partial class MyControl : Control
{
    partial void OnIsActiveChanged(bool oldValue, bool newValue)
    {
        // 変更時の処理だけ書けばOK!最高!!!
    }
}

ここが最高!:On{}Changed 自動検出
Afterのコードを見て「あれ、コールバックの登録はどこでやってるの?」と思った方、鋭いです!
本ジェネレーターは、On{プロパティ名}Changed という命名規則で partial メソッドを定義しておくだけで、それを自動検出し、裏側の PropertyMetadata に勝手にフックしてくれます。開発者は変更時のロジックを書くだけで完了です。

2. なぜフォークしたのか? 狂気の「ゼロアロケーション」へのこだわり

フォーク元であるHavenDV氏のライブラリも非常に素晴らしいのですが、大規模プロジェクトに導入した際、IDEに負荷がかかり不要なガベージコレクションが発生してしまう点に課題を感じていました。

Source Generatorは、開発環境上でコードを1文字打つたびにバックグラウンドで走ります。ここで中間文字列などのメモリを確保する、いわゆるアロケーションが発生するジェネレーターを使うと、ガベージコレクションが頻発してIDEがフリーズしたり、タイピングがもたついたりします。

そこで本フォーク版では、Gen2 GCを100%撲滅しました。

  • ClassScopeSourceWriter といった ref struct ベースの独自コード合成エンジンを完全新規で開発。
  • 中間文字列のメモリ割り当てを徹底排除

結果として、処理速度は+30%向上し、スループットは+62.4%向上しました!
メモリを食わない、GCが走らないからとにかく速い。プロパティが数千個あるような超大規模ソリューションにぶち込んでも、皆さんのタイピング遅延を一切引き起こしません。

3. サイレントエラーを許さない厳格なコンパイル時型安全

フォーク元のジェネレーターにあったもう一つの弱点として、「コールバックメソッドの引数の型をうっかり間違えると、警告が出ないまま裏で null が登録されて動かなくなる」という致命的なバグがありました。これ、デバッグ時にめちゃくちゃ沼る原因になります。

本ライブラリではこの問題を完全に排除!
シグネチャの不一致などは即座に DPG0001 などのコンパイルエラーとして検出します。実行する前にエディタ上で赤線として気づけるので、安全性が桁違いです。

4. モダンC#フル活用でさらにスマートに

C# 11以降の機能を前提とし、記述量と安全性をさらに高める設計を採用しています。

  • C# 11+ ジェネリック属性: typeof(T) なんて野暮な記述は不要。[DependencyProperty<string>] と直感的に書けます。
  • ターゲット型 new(...) の自動展開: DefaultValueExpression = "new(42)" と書けば、式を動的評価して式木から安全に完全修飾コンストラクタに自動展開されます。
  • XMLドキュメントの自動合成: Description を設定すれば、インテリセンス用のXMLコメントまで自動で生やしてくれます。

5. マルチプラットフォーム対応で主要UIフレームワークを完全網羅

WPF専用? いえいえ、モダンなC#開発環境をフルカバーしています。

  • WPF / .NET MAUI / Avalonia / WinUI 3 / Uno Platform / UWP

Avaloniaの DirectProperty や MAUIの BindableProperty、さらにはコールバックの型の違いといった各プラットフォームで微妙に異なるAPIの仕様は、内部のストラテジーが自動で吸収します。開発者は「どのフレームワークでも同じ属性構文で書ける」という極上の体験を得られます。

6. 日本語・英語両対応の詳細なドキュメント完備!迷わず導入できます

OSSのライブラリを導入する際、「コードを読まないと使い方がわからない」というのは大きなストレスですよね。

本プロジェクトでは、基本的な使い方から各属性の詳しい仕様、アーキテクチャの内部設計、プラットフォームごとの差異に至るまで、徹底的にドキュメントを完備しています。リポジトリには英語だけでなく日本語の詳細な仕様書(Spec)もフルで用意しているため、日本の開発者の皆様も安心して、迷うことなくすぐにプロジェクトへ組み込んでいただけます。

まとめ:MITライセンスだから煮るなり焼くなり好きにしろ!

ライセンスはもちろん、フォーク元と同じくMITライセンスです。
「肉なり焼くなり、煮るなり好きにしろ!」というくらい自由で使いやすいライセンスですので、個人開発からゴリゴリのエンタープライズな商用・大規模ソリューションまで、どこでも安心して使っていただけます。

WPFやMAUI、Avaloniaで開発をしていて、ボイラープレートに辟易している方は、ぜひNuGetからインストールして試してみてください!

IDEサクサク、タイピング量激減の快適なUI開発ライフが待っています!!
使ってみて良かったら、GitHubでStar ⭐ をもらえると開発のモチベーションに繋がります! IssueやPRやDiscussionも大歓迎です!

3
3
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
3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?