我有一个内部类,其中包含实现细节,包括属性,这些细节不应公开访问。我必须将这个类传递给公共(public)调用者,并允许他们传递它、存储它、序列化它,或者基本上用它做任何他们想做的事情。该类可以通过两种不同的方式公开访问。这些方式作为两个公共(public)接口(interface)公开。我想阻止用户在两个公共(public)接口(interface)之间进行转换。这是一些代码来演示我正在谈论的内容。
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.....
类(class)ContainsDetails
只是为了演示。在我的实际代码中,程序集扮演 ContainsDetails
的角色。同样,Detail
是 internal
我的实际代码中的类。
在这里,用户知道 IFooPlus
和IFoo
。用户不知道Detail
存在。用户也不知道 LessDetail
返回的对象可转换为IFooPlus
。我的代码返回相同的 Detail
在不同时间向用户发出对象,并将其返回为 IFoo
或IFooPlus
取决于Detail
的一些复杂状态和其他内部对象。另请注意 ProcessFoo
ContainsDetails
中的方法。我的代码需要能够接受 IFoo
来自用户,并将其处理为 Detail
。
我想要 Actor var more = (ContainsDetails.IFooPlus)(container.LessDetail)
生成 InvalidCastException
。对所有 IFooPlus
进行运行时检查的成本过高。操作来确定 Detail
是否对象对于这些操作处于正确的状态。相反,我希望用户永远无法处理 IFoo
作为IFooPlus
.
我能想到的唯一选择是嵌入一些 IFoo
Detail
内的成员子类并有 Detail
子类之间保存着彼此的引用。恶心。
是否有防止这种类型转换的最佳实践,或者我应该附上 IFoo
Detail
的成员子类中的功能?
最佳答案
最简单的方法是使用一个只读包装器,它具有对可写包装器的引用。因此,LessDetail
将始终返回相同的包装器引用,但 MoreDetail
将返回对“真实”类型的引用。然后,您可以使它们都实现一个内部接口(interface),该接口(interface)允许您执行所需的任何操作,而包装器可能会将这些调用代理到底层对象。
或者,您可以尝试重新审视您的设计 - 目前听起来并不理想,要么无法在类型之间进行转换,要么 ProcessFoo
接受 编译时的任何 IFoo
,但实际上只能处理一种特定的实现。对我来说,这感觉就像是滥用继承权。
关于c# - 防止两个接口(interface)之间的转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11389900/