4

書き込み専用の依存関係プロパティを作成するための手順を知る必要があります。DependencyProperty クラスには書き込み専用プロパティ用の特別な "Register" メソッドがないことがわかりますが、RegisterAttached メソッドが私がやろうとしていることに適用できるかどうかはわかりません。

このプロパティは、単純な CLR プロパティではなく、依存関係プロパティである必要があります。内部的には、私のクラスは、安定性を維持するために、このプロパティに PropertyChangedCallback を必要とします。


Pro C# 2008 and the .NET 3.5 Platform, Page 1061に明確に記載されているため、書き込み専用の依存関係プロパティを作成できることは知っています。
ただし、これは、同じページで「依存関係プロパティ」と「書き込み専用」を見つけることができる唯一の場所です。そして、この著者は、基本的な読み取り/書き込み依存関係プロパティ以外の手順を実際に読者に示す必要はないと考えていたようです。もちろん、この本は大雑把かもしれませんが、この本はかなり標準的に見えるので、著者が正しいというのはかなり安全な賭けだと思います. インターネット上で情報が不足しているのは、一般的にこのようなプロパティを作成する必要がある人がいないという事実に起因すると思います.

独自の書き込み専用の依存関係プロパティを作成したいというのは、非常に疑わしいと思います。私が望むところは理にかなっていることを保証します。私のクラスには、値を設定するオブジェクトにのみ役立つプロパティがあります。後で別のオブジェクトがこのプロパティの値を要求した場合、セッターの元のコンテキストを知らなければ、値から合理的な意味を理解することはできません。

このプロパティは、情報提供を目的として使用することを意図したものではありません。外部オブジェクトがこのようにプロパティ値を使用しようとすることは、問題があり、危険であり、セキュリティ リスクです。したがって、このプロパティでの読み取り操作を禁止するのが最善の設計だと思います。私のクラスを使用する人は誰でも、クラスを意図したとおりに使用せざるを得ないことに気付くでしょう。

4

4 に答える 4

4

できません。これは仕様によるもののようです。言及された本に対するあなたのアプローチを理解することができ、その品質に疑問を呈することは決してありませんが、それでもこれはある種のコピー&ペーストまたは同様の問題であると推測します。これが私の推論です:

WPFプロパティシステムコード

WPFプロパティシステムの設計

  • さらに重要なのは、'XAMLプロセッサの現在のWPF実装は、本質的に依存関係プロパティを認識していることです。WPF XAMLプロセッサは、バイナリXAMLをロードし、依存関係プロパティである属性を処理するときに、依存関係プロパティにプロパティシステムメソッドを使用します。これにより、プロパティラッパーが効果的にバイパスされます。XAMLの読み込みと依存関係のプロパティを参照してください。
  • 最も重要なのは、'依存関係プロパティは一般にパブリックプロパティと見なされるべきです。Windows Presentation Foundation(WPF)プロパティシステムの性質上、依存関係プロパティの値についてセキュリティを保証することはできません。依存関係プロパティのセキュリティを参照してください。

特に後者の2つのポイントは、CLRラッパーがアクセス制限されているか利用可能であるかに関係なく、依存関係プロパティ値は常にGetValue() / SetValue()を介してアクセスできるという設計上の制約の概要を示しています。ただし、特に考慮されているのは例外です。読み取り専用の依存関係プロパティ

したがって、ジェフズの回答がすでに示唆しているように、たとえばゲッターを削除するだけでは、 GetValue()を介してプロパティにアクセスする人を実際に防ぐことはできませんが、少なくとも「カスタムクラスのすぐに公開される名前空間を減らすことができます」 。ジェフによって提案されたように、プロパティ値をいくらか見にくく/アクセスしにくくし、取得した値をクライアントにとって本質的に役に立たないものにするというこのようなセマンティック回避策の有用性は、もちろん特定のシナリオによって異なります。

于 2009-08-25T00:12:42.503 に答える
0

依存関係プロパティ定義で適用されCoerceValueCallbackたプロパティを介して、プロパティに関連付けられたを使用できるようです。FrameworkPropertyMetadata2 番目の引数である新しい値を取り、それを独自の書き込み専用メカニズムを介してオブジェクトに渡し、null(または値型の場合はdefault(T)) を返すコールバックをインストールするだけです。

「.NET は強制前の元の値を記憶している」のは事実ですが、データ バインディングを介して伝播されることはありません。への呼び出しGetValueは強制された値を返しますが、これは何もリークしません。

これを使用して、一連のバイトであるプライマリ プロパティの値に対して一方向のコンビニエンス セッターを実装しています。たとえば、ユーザーは文字列をバインドして、プライマリ プロパティをエンコードされたバイト (設定されているプロパティに応じて ASCII または UTF-8) に設定できます。ただし、すべてのバイト シーケンスが有効な UTF-8 であるとは限らないため、変換を逆にして、コンビニエンス プロパティを介して文字列を読み取ることはできません。

public string AsciiData
{
    set { BinaryArray = Encoding.ASCII.GetBytes(value); }
}

public static readonly DependencyProperty AsciiDataProperty =
    DependencyProperty.Register("AsciiData",
        typeof(string),
        typeof(HexView),
        new FrameworkPropertyMetadata(null, CoerceAsciiData));

private static object CoerceAsciiData(DependencyObject target, object value)
{
    (target as HexView).AsciiData = value as string;
    return null;
}

強制ハンドラーはメタデータの置換によって削除できるため、これはセキュリティを提供しませんが、開発者が間違った方法でカップリングを誤って作成することを防ぎます。

于 2014-06-12T17:30:58.300 に答える
-1

「get」で何も返さない理由がわかりません。

さらに、Jeff の例では、'OnMyWriteOnlyDependencyPropertyPropertyChanged' を実装していないだけかもしれません。

誰もそれを読むことができなければ、イベントを開催する本当の理由はありませんよね?

于 2009-08-25T00:47:02.607 に答える