C# 防止在两个接口之间强制转换
我有一个内部类,它包含实现细节,包括属性,不应该公开访问。我必须将这个类传递给公共调用方,并允许他们传递、存储、序列化它,或者基本上用它做任何他们想做的事情。该类可以通过两种不同的方式公开访问。这些方法公开为两个公共接口。我想防止用户在两个公共接口之间强制转换。下面是一些代码来演示我所说的内容C# 防止在两个接口之间强制转换,c#,.net,interface,polymorphism,implementation,C#,.net,Interface,Polymorphism,Implementation,我有一个内部类,它包含实现细节,包括属性,不应该公开访问。我必须将这个类传递给公共调用方,并允许他们传递、存储、序列化它,或者基本上用它做任何他们想做的事情。该类可以通过两种不同的方式公开访问。这些方法公开为两个公共接口。我想防止用户在两个公共接口之间强制转换。下面是一些代码来演示我所说的内容 void Main() { var container = new ContainsDetails(5); Console.WriteLine(container.LessDetail.
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
的角色。类似地,Detail
在我的实际代码中是一个internal
类
在这里,用户了解IFooPlus
和IFoo
。用户不知道存在详细信息
。用户也不知道LessDetail
返回的对象是否可转换为IFooPlus
。我的代码在不同的时间向用户返回相同的Detail
对象,并根据Detail
和其他内部对象的复杂状态,将其作为IFoo
或IFooPlus
返回。还要注意中的ProcessFoo
方法包含详细信息。我的代码需要能够接受来自用户的IFoo
,并将其作为详细信息处理
我想让castvar more=(ContainsDetails.IFooPlus)(container.LessDetail)
生成一个InvalidCastException
。对所有IFooPlus
操作执行运行时检查以确定Detail
对象对于这些操作是否处于正确状态的成本过高。相反,我希望用户永远不能将IFoo
视为IFooPlus
我能想到的唯一选择是在Detail
中嵌入一些IFoo
成员子类,并让Detail
和子类相互引用。恶心
是否有防止此类强制转换的最佳实践,或者我是否应该将IFoo
功能包含在Detail
的成员子类中?最简单的方法是使用一个只读包装器,其中引用了可写的包装器。因此LessDetail
将始终返回相同的包装器引用,但是moredeail
将返回对“real”类型的引用。然后,您可以让它们都实现一个内部接口,该接口允许您做任何需要做的事情,包装器可能会将这些调用代理给底层对象
或者,您可以尝试重新审视您的设计—目前听起来并不理想,因为无法在类型之间转换,或者ProcessFoo
在编译时接受任何IFoo
,但实际上只能处理一个特定的实现。这对我来说就像是滥用继承。事实上,IFoo是IAsyncResult,ProcessFoo是BeginReadxxx、EndRead、BeginWritexxx等。我不能接受比IFoo(IAsyncResult)更严格的限制,因为我的代码需要符合旧的异步模式。@MichaelGraczyk:这很难看,但至少是一个合理的解释。这就是为什么在这个问题中提供上下文是值得的…是的,我希望有一些创造性的方法来覆盖casting操作符,只抛出一个异常IFoo
和IFooPlus
与线程同步代码紧密耦合。在用户的回调中,我必须小心不要更改状态:)。如果这样的强制转换覆盖不存在,我将尝试使用只读包装类。谢谢