それはのために渡します。.NET不変オブジェクト
public class Entity
{
private int ID1;
public int ID
{
get { return ID1; }
}
}
が、これのためにされていません。
public class Entity
{
public int ID { get; private set; }
}
ここでは「WTF?」という質問になります。
それはのために渡します。.NET不変オブジェクト
public class Entity
{
private int ID1;
public int ID
{
get { return ID1; }
}
}
が、これのためにされていません。
public class Entity
{
public int ID { get; private set; }
}
ここでは「WTF?」という質問になります。
他の場所に投稿された回答への小さな変更。保護されたパブリックセッターを持つプロパティが少なくとも1つ存在する場合、次の値は0以外を返します。 GetSetMethodがIsPublic(publicのみ)ではなくnull(セッターなし)とIsPrivate(つまりパブリックではないか保護されている)のテストを返すかどうかを確認します。
var setterCount =
(from s in typeof(Entity).GetProperties(
BindingFlags.Public
| BindingFlags.NonPublic
| BindingFlags.Instance)
where
s.GetSetMethod(true) != null // setter available
&& (!s.GetSetMethod(true).IsPrivate)
select s).Count();
はそれにもかかわらず、pointed out in Daniel Brückner's answerように、クラスはない公に可視性セッターを有することが必要であるが、クラスのない十分条件は不変と見なされるべきです。
確かに、あなたのprivate set
は2番目のものです。
最初に、クラスEntity
のインスタンスは、外部クラスによってID1プロパティが書き込まれることがあります。後者で
は、セッターは、クラス自体にプライベートですので、唯一の(つまりはそれ自身のコンストラクタ/初期化子)は
が第二に、あなたのセッターのうちprivate
を取り、それが必要エンティティ内から呼び出すことができますpass
ID1はバッキングフィールドであり、ファーストクラスのプロパティではなく、ゲッターを介して外部に読み込まれます。外部のクラスからどのようにアクセスできるのですか? –
彼の元の例では、彼は最初のプロパティのパブリックセッターを持っていた。彼は以来、質問を編集しています。 http://stackoverflow.com/revisions/839066/list –
私は参照してください。ありがとうEoin。 –
私はCanWriteが、セッターがあれば真を返すと言います。プライベートセッターもセッターです。
パブリックセッターがあるため、初回通過時に少し驚いています。私がまだカフェインで低すぎない限り、設定数は1であるため、アサーションは失敗するはずです。 CanWriteは両方に対してtrueを返すだけなので、両方とも失敗するはずです。 (そして、linqクエリはIDを含むpublicプロパティをpublicとして取得するだけです)
(編集)これで、ファーストクラスのコードが変更されたので、もうsetterがありません。
これは、CanWriteがsetterメソッドのアクセサを見ていることを前提としていますが、そうではありません。なぜなら公共ゲッターの - - プロパティが公開されていることを、
var setterCount =
(from s in typeof (Entity).GetProperties(BindingFlags.Public | BindingFlags.Instance)
where s.GetSetMethod().IsPublic
select s)
.Count();
私はちょうどコードを試したことがあり、私は同意します。私は両方のテストクラスのために1セッターのカウントを取得します。 –
私がカフェインで低すぎない限り、最初のケースではセッターが表示されません。 ID1はメンバ変数でありプロパティではないので、 "セッタ"メソッドはありません。 –
。 代わりにTSが行うべきことは、propertyinfoでGetSetMethod()を呼び出し、返されたMethodInfoでIsPublicが真であるかどうかをチェックすることです。 –
問題があり、それは書き込み可能である - なぜなら、民間セッター:あなたが行う必要があります。あなたはあなたのテストを洗練させる必要があります。
さらに、メソッド内のプライベートデータを変更できるため、このように不変性を保証することはできません。不変性を保証するためには、すべてのフィールドが読み取り専用で宣言され、自動実装されたプロパティがないことを確認する必要があります。あなたが簡単なタイプ彼らの不変のため
typeof(MyType).IsImmutable()
とインスタンス
myInstance.IsImmutable()
をテストすることができ、この拡張メソッドで
public static Boolean IsImmutable(this Type type)
{
const BindingFlags flags = BindingFlags.Instance |
BindingFlags.NonPublic |
BindingFlags.Public;
return type.GetFields(flags).All(f => f.IsInitOnly);
}
public static Boolean IsImmutable(this Object @object)
{
return (@object == null) || @object.GetType().IsImmutable();
}
。インスタンスフィールドを見ると
注意
readonly
フィールドを変更することはできます。FiledInfo.FieldType.IsImmutable()
で行うことはできません。'object'と' bool'の代わりに 'Object'と' Boolean'を使う理由はありますか? –
コンパイラが文字列、bool、int、オブジェクト、およびその他すべてのものに対して生成するものに依存しない(コンパイラには選択肢がないことがわかりますが) )。 –
これには十分な理由がありますか? –
あなたはおそらく、セット方法と、GETメソッドは、同じアクセス修飾子を持っていないので、あなたはPropertyInfo自体に頼ることができない
propertyInfo.GetSetMethod().IsPublic
を呼び出す必要があります。
var setterCount =
(from s in typeof (Entity).GetProperties(
BindingFlags.Public
| BindingFlags.NonPublic
| BindingFlags.Instance)
where
s.GetSetMethod() != null // public setter available
select s)
+1これはほぼあります。しかしGetSetMethod()は、プライベートセッターやセッターのないプロパティに対してはnullを返します。これを変更してnullをテストする必要があります。 – Joe
@Joe:OK、CanWriteはもう必要ありません –
ProPrtyInfo.GetSetMethod()は、ProeprtyInfoを呼び出さない限り、public setメソッドのみを返すため、s.GetSetMethod()。IsPublicは不要です。 GetSetMethod(Boolean nonPublic)。 –
私が正しく理解していれば、エンティティは不変になります。 もしそうなら、テストは
var setterCount = (from s in typeof(string).GetProperties(BindingFlags.Public | BindingFlags.Instance).Select(p => p.GetSetMethod())
where s != null && s.IsPublic
select s).Count();
Assert.That(setterCount == 0, Is.True, "Immutable rule is broken");
アサーションが正しい - setterCount == 0が真であり、このテストが失敗した場合、アサーションに "不変ルールが壊れている"というメッセージが表示される場合、タイプは不変です。 –
固定、ありがとうDaniel – SeeR
に変更する必要があります私はにプロパティ条件の変更をお勧め:
s.CanWrite && s.GetSetMethod().IsPublic
は、あなたがそのCanWriteプロパティ真実が何であるかの特性を見るために、それをデバッグしようとしたことがありあなたのLINQクエリによって返されていますか?どうやら、それはあなたが期待していないことを拾っています。その知識があれば、LINQクエリをより選択的にして、必要な方法で作業することができます。 また、@Daniel Brucknerは、フィールドも読み取り専用でない限り、クラスが完全に可変ではないことに同意します。呼び出し元はメソッドを呼び出したり、getterを介して読み取り専用として公開されているプライベートフィールドを内部的に変更するgetterを使用することがあります。これにより、不変ルールが破られ、クライアントが驚くことになり、問題が発生します。変更可能なオブジェクトの操作は、副作用を持ってはいけません。
CanWrite == trueはsetterの存在を保証するため、テストs.GetSetMethod(true)!= nullが余分です。 –
true、 "s.GetSetMethod(true)!= null"はCanWriteが真であることと等価であるため、そのうちの1つは冗長です。 IsPrivateプロパティを逆参照する前に、nullをテストすることについて明示的にしたいので、CanWriteを削除しました。 – Joe