フォントが不変であることは、毎回新しいインスタンスを作成する必要があるため、プログラマーと GC の両方を悩ませます。
では、なぜ Font は不変の参照型なのでしょうか?
フォントが不変であることは、毎回新しいインスタンスを作成する必要があるため、プログラマーと GC の両方を悩ませます。
では、なぜ Font は不変の参照型なのでしょうか?
これにより、レンダリング システムからの使用が簡素化されます。
フレームワークが Font を可変にできるようにする場合、変更を検出し、定期的にレンダリングがどのように行われるかを再調整する必要があります。Font はネイティブ リソースを作成するため、これを不変に保つことで、システムが繰り返し内部でハンドルを再作成しなければならないことを心配する必要がなくなります。
また、「プログラマーへの苦痛」という点では同意しません。Font を不変にすることで、ユーザーが Font オブジェクトを作成したときに何が起こっているのかがより明確になります。新しい Font が必要な場合は、新しい Font オブジェクトを作成する必要があります。これにより、新しいネイティブ フォント リソースが作成されます。Font を不変にすると、何が起こっているのかがより明確になります。誤ってパフォーマンスの問題を引き起こす可能性が低くなります。
Font がミュータブルであれば、Font プロパティを変更するたびにハンドルを繰り返し作成していたことがわかりにくくなります。
さて、いくつか質問してみてください。
まず、フォントは論理的に食料品リストのように変更可能なものなのか、それとも数字のように不変なものなのか? プログラムで食料品リストをモデリングしている場合、通常、特定のアイテムがなくなるか購入すると内容が変化する 1 つの食料品リストを持つことを考えるので、それを変更可能にすることは理にかなっています。しかし、あなたが典型的にモデル化する数字は、不変である - 数字の 12 は、今も、そして永遠に、数字の 12 である。
「Helvetica 12 point bold」は、数値のような固定された不変のものであり、変更できるものではないと考えています。
第二に、フォントは論理的にコピーを作成できる値に近いものですか、それとも参照できる単一のものに近いものですか? Helvetica の「2 つのコピー」を所有することは考えていません。Helveticaを参考にしようと思います。数字は、さまざまな目的のためにさまざまなコピーを持っていると思いますが、食料品リストに12個のアイテムがあり、キーリングに12個のキーがある場合、これらの両方を「12を指す」とは考えていません.
私はフォントを可変で値によってコピーされるのではなく、不変で参照されるものと考えているので、個人的にはフォントを不変の参照型としてモデル化します。おそらく、フォントに関するあなたの直感は私のものとは異なるでしょう。
IDisposable
基礎となるオブジェクトをラップし、適切な実装を提供するファイナライザーが必要なため、それらは構造体ではありません。Dispose()
のコピーを自分で作成した場合はどうなりますstruct
か? 毎回ハンドルを複製しますか?
GCにはそれほどストレスはありません...
またFont
、操作の途中で変更されることを心配することなく、安全に再利用することができます;-p
これがプログラマーを悩ませることに同意しません。BCL には、プログラマーによって日常的に使用され、問題を引き起こさない不変の型がたくさんあります。たとえば、System.String。
不変であることの利点の 1 つは、毎回新しいインスタンスを作成する必要がないことです。同じフォント タイプは変更されないため、何度でも再利用できます。一方、それが変更可能である場合は、他の誰もあなたの下からそれを変更しないことを保証するために、毎回コピーを作成する必要があります.
最後に、Font は厳密な意味での不変クラスではありません。IDisposable を実装し、Dispose メソッドで基になるネイティブ オブジェクトを破棄します。
Font は設計が不十分なオブジェクトであり、単一責任の原則に違反しており、あなたが引用する困難はこれから生じます。Font の問題は、(1) フォントの描画方法の説明と、(2) これらのプロパティを持つフォントの GDI フォント オブジェクトです。前者の型は結果を伴わずに変更可能ですが、後者の型を変更可能にするとあらゆる種類の問題が発生します。
とりわけ、典型的なコントロール (ボタンなど) の Font プロパティの所有権をどのように追跡すべきかという問題を考えてみてください。コントロールに関連付けられたフォントを時々変更する場合は、コントロールごとに個別の Font オブジェクトを作成し、コントロールのフォントを別のものに変更するときにそれを破棄するか、使用しているすべての異なるフォントのリストを保持する必要があります。過剰な数の同一の Font オブジェクトを作成しないようにするにはどうすればよいでしょうか?
FontDescription 構造体 (変更可能で、IDisposable ではない) が存在し、Control.Font のようなものが FontDescription 型である場合 (またはさらに良いことに、Control が FontDescription 型のパラメーターを持つ SetFont メソッドを公開した場合)、上記の質問には非常に簡単に答えることができます。 . 現状では、コントロールの Font を設定するための最も効率的な方法は、新しいフォント オブジェクトを作成し (まだ適切なオブジェクトがない場合)、すぐに破棄してから割り当てを行うことです。Font の「フォントの説明」部分は Disposal 後も準有効なままであり、Control.Font プロパティに本当に必要なのはそれだけです。
それは開発者を悩ませていると主張することができます。しかし、逆の場合でも同じ議論をすることができます。
例えば:
// Let me just set the button to the same font as the textbox...
button.Font = textBox.Font;
// ...except that I want the button's font to be bold.
button.Font.Bold = true;
Font
上記のコードは、開発者の期待に反して、変更可能な場合、ボタンとテキストボックスのフォントを同時に太字に設定します。