如果我有一个类(P类)使用其他一些可重用的组件(C类)(例如状态管理器),那么如果该组件需要访问我的顶级类(P)中的一些数据那么我有什么选择?
关键是我不希望将这些数据暴露给外界,只是在我知道并信任并在P中使用的组件中。
public static class Program
{
private void Main()
{
var owner = new Owner();
// I can call Foo()!!!
((IOwner)owner).Foo();
}
}
public interface IOwner
{
void Foo();
}
public class Owner : IOwner
{
private Component m_component;
public void SomeExternalAPI()
{
m_component = new Component(this);
m_component.DoSomething();
}
void IOwner.Foo()
{
// do something
}
}
public class Component
{
private readonly IOwner m_owner;
public Component(IOwner owner)
{
m_owner = owner;
}
public void DoSomething()
{
m_owner.Foo();
}
}
我可以在P上使用接口,但这会在外部公开数据。 我可以在P上使用显式接口,但这可以是强制转换,因此也很容易公开数据。
如果我可以以某种方式传授"友谊"在组件(我创建,理想情况下在实例级别!)上,并使IOwner成为仅限朋友的界面,它将是安全的。
我知道目前在C#中这是不可能的。
它经常出现在我身上。
有没有人有任何解决方案或建议?
答案 0 :(得分:0)
您可以在界面和internal
课程中使用Component
访问者。
internal interface IOwner
{
void Foo();
}
internal class Component
{
private readonly IOwner m_owner;
public Component(IOwner owner)
{
m_owner = owner;
}
public void DoSomething()
{
m_owner.Foo();
}
}
Owner
课程为public
public class Owner : IOwner
{
private Component m_component;
public void SomeExternalAPI()
{
m_component = new Component(this);
m_component.DoSomething();
}
void IOwner.Foo()
{
// do something
}
}
使用这种方法,将无法从外部程序集
访问界面和Component类客户只会看到 Owner
类及其SomeExternalAPI()
方法。
var Owner = new Owner();
owner.SomeExternalAPI();
//owner.Foo() --> Won't compile!
//((IOwner)owner).Foo() --> Won't compile!
答案 1 :(得分:0)
我认为我找到了一个合理的解决方案,尽管它的工作非常辛苦,代码比我想要的还要多
使用代理类,它实现了公共IOwner接口,但是可以使用内部的IInternalOwner接口调用实际所有者,该接口是在构造时给出的。
然后,代理就像一个令牌,允许所有者为其提供此令牌的人调用。它的代码比我想要的多,如果将它构建到C#中会很好: - )。
但是,它在程序集之间起作用(实际上我有4个来测试它!)。
public class Owner : IInternalOwner
{
private ITheComponent m_component;
public void SomeExternalAPI()
{
var proxy = new Proxy(this);
m_component = ClassFactory.ConstructTheComponent(proxy);
m_component.DoSomething();
}
void IInternalOwner.Foo()
{
// do something
Console.WriteLine("Owner.Foo was called");
}
private class Proxy : IOwner
{
private IInternalOwner m_owner;
public Proxy(IInternalOwner owner)
{
m_owner = owner;
}
/// <summary>
/// pass through for each method & property!
/// </summary>
public void Foo()
{
m_owner.Foo();
}
}
}
internal interface IInternalOwner
{
void Foo();
}