我有一个内部类,其中包含不应公开访问的实现细节,包括属性。我必须将这个类传递给公共调用者,并允许他们传递它、存储它、序列化它,或者基本上做他们想做的任何事情。可以通过两种不同的方式公开访问该类。这些方式公开为两个公共接口。我想阻止用户在两个公共接口之间进行转换。这是一些代码来演示我在说什么。
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
来自用户的 a,并将其作为Detail
.
我想让演员var more = (ContainsDetails.IFooPlus)(container.LessDetail)
生成一个InvalidCastException
. IFooPlus
对所有操作进行运行时检查以确定Detail
对象是否处于这些操作的正确状态是非常昂贵的。相反,我希望用户永远不能将 aIFoo
视为IFooPlus
.
我能想到的唯一选择是在其中嵌入一些IFoo
成员子类,Detail
并让 theDetail
和子类相互引用。呸。
是否有防止这种类型转换的最佳实践,或者我应该将IFoo
功能包含在成员子类中Detail
?