プロパティを含む実装の詳細を含む内部クラスがありますが、パブリックにアクセスすることはできません。このクラスを公開呼び出し元に渡して、それらを渡したり、保存したり、シリアル化したり、基本的に好きなことをしたりできるようにする必要があります。クラスは、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またはそれに応じて返します。の方法にも注意してください。私のコードは、ユーザーからを受け取り、 として処理できる必要があります。 IFooPlusDetailProcessFooContainsDetailsIFooDetail
var more = (ContainsDetails.IFooPlus)(container.LessDetail)キャストが を生成するようにしたいと思いInvalidCastExceptionます。オブジェクトがそれらの操作に対して正しい状態にあるIFooPlusかどうかを判断するために、すべての操作に対して実行時チェックを行うのは非常にコストがかかります。代わりに、ユーザーが をとしてDetail扱えないようにしたいと思います。IFooIFooPlus
私が考えることができる唯一のオプションは、IFooメンバーのサブクラスを内部に埋め込みDetail、Detailとサブクラスが相互に参照を保持するようにすることです。うん。
IFooこの種のキャストを防止するためのベスト プラクティスはありますか、それとも機能を のメンバー サブクラスで囲む必要がありDetailますか?