プロパティを含む実装の詳細を含む内部クラスがありますが、パブリックにアクセスすることはできません。このクラスを公開呼び出し元に渡して、それらを渡したり、保存したり、シリアル化したり、基本的に好きなことをしたりできるようにする必要があります。クラスは、2 つの異なる方法でパブリックにアクセスできます。これらの方法は、2 つのパブリック インターフェイスとして公開されます。ユーザーが 2 つのパブリック インターフェイス間でキャストできないようにしたいと考えています。ここに、私が話していることを示すコードをいくつか示します。
void Main()
{
var container = new ContainsDetails(5);
Console.WriteLine(container.LessDetail.TheDetails);
var more = (ContainsDetails.IFooPlus)(container.LessDetail);
more.TheDetails = 10;
Console.WriteLine(container.LessDetail.TheDetails);
}
public class ContainsDetails {
public interface IFooPlus {
int TheDetails {
get;
set;
}
}
public interface IFoo {
int TheDetails {
get;
}
}
private readonly Detail _myDetail;
public ContainsDetails(int x) {
_myDetail = new Detail(x);
}
public IFoo LessDetail {
get {
return _myDetail;
}
}
public IFooPlus MoreDetail {
get {
return _myDetail;
}
}
public bool ProcessFoo(IFoo foo) {
var theDeets = foo as Detail;
if (theDeets != null) {
return theDeets.TheDetails++%2 == 0;
} else {
throw new ArgumentException("foo argument must have originated from ContainsDetails.");
}
}
private class Detail : IFooPlus, IFoo {
private int _myX;
private Detail() {}
internal Detail(int x) {
_myX = x;
}
public int TheDetails {
get {return _myX; }
set { _myX = value; }
}
}
}
出力は次のとおりです。
5
10
上記の出力を次のようにしたいと思います。
5
System.InvalidCastException thrown.....
クラスContainsDetails
はデモンストレーションのために存在します。私の実際のコードでは、アセンブリが の役割を果たしContainsDetails
ます。同様に、私の実際のコードDetail
のinternal
クラスです。
IFooPlus
ここで、ユーザーはとの両方について知っていますIFoo
。ユーザーはそれが存在することを知りませんDetail
。LessDetail
ユーザーは、 によって返されるオブジェクトが に変換可能であることも知りませんIFooPlus
。私のコードは、Detail
さまざまな時点で同じオブジェクトをユーザーに返し、他の内部オブジェクトの複雑な状態に応じて、IFoo
またはそれに応じて返します。の方法にも注意してください。私のコードは、ユーザーからを受け取り、 として処理できる必要があります。 IFooPlus
Detail
ProcessFoo
ContainsDetails
IFoo
Detail
var more = (ContainsDetails.IFooPlus)(container.LessDetail)
キャストが を生成するようにしたいと思いInvalidCastException
ます。オブジェクトがそれらの操作に対して正しい状態にあるIFooPlus
かどうかを判断するために、すべての操作に対して実行時チェックを行うのは非常にコストがかかります。代わりに、ユーザーが をとしてDetail
扱えないようにしたいと思います。IFoo
IFooPlus
私が考えることができる唯一のオプションは、IFoo
メンバーのサブクラスを内部に埋め込みDetail
、Detail
とサブクラスが相互に参照を保持するようにすることです。うん。
IFoo
この種のキャストを防止するためのベスト プラクティスはありますか、それとも機能を のメンバー サブクラスで囲む必要がありDetail
ますか?