limit方法只能由特定类调用

jlt*_*rem 22 c#

我希望一个类中的特定方法只能由特定类访问.例如:

public class A
{
  public void LimitedAccess() {}
  public void FullAccess() {}
}

public class B
{
  public void Func()
  {
     A a = new A();
     a.LimitedAccess();       // want to be able to call this only from class B
  }
} 

public class C
{
  public void Func()
  {
     A a = new A();
     a.FullAccess();           // want to be able to call this method
     a.LimitedAccess();        // but want this to fail compile
  }
} 
Run Code Online (Sandbox Code Playgroud)

是否有可用于强制执行此操作的关键字或属性?

更新:

由于现有的系统复杂性和时间限制,我需要一个低影响力的解决方案.我想在编译时指出无法使用LimitedAccess().我相信Jon Skeet的答案正是我所要求的无法在C#中完成.

这个问题和乔恩的回答对那些可能会遇到这个问题的人有好处.事实上,这种设计气味可以让任何人选择这样的东西作为理想的解决方案.

正如评论中所提到的,如果您正在尝试解决类似的情况,那么C#朋友对话很有用.

至于我的特定解决方案:"为什么A会包含B的逻辑"(@sysexpand在评论中提到).这就是问题所在. B.Func()在我正在研究的整个系统中被调用,但它主要是在一个单独的系统上运行A.所以我落得这样做移动BFunc()进入A,使A.LimitedAccess()私人.还有一些其他细节可以解决,但总是有,但我得到了一个低影响的解决方案,给了我调用者的编译时错误A.LimitedAccess().

谢谢你的讨论.

Jon*_*eet 23

不可以.你唯一能做的就是创建LimitedAccess一个私有方法,并B在类中嵌套类A.

(我假设你想在同一程序中的所有类.否则,你可以把AB在同一程序,并C在不同的装配,使LimitedAccess一个internal方法.)

  • 实际上还有另一种方法,但是这需要特定的类创建对象,并且创建的类将接口实现暴露为out方法(`new A(out limitedAccessMethods)`).当然,这需要`A`中的私有嵌套类,它实现了接口,但只允许创建类访问.然而,从设计的角度来看它是否很好是值得怀疑的.当然它有限. (2认同)

cow*_*tor 5

假设您只想限制对特定实例的方法和变量的访问,则可以通过使用接口来实现此效果。但是,它不会阻止某人创建自己的类实例,此时他们将拥有对该实例的完全访问权限。

public interface IA
{
  void FullAccess();
}


public class A : IA
{
  public void LimitedAccess() {}  //does not implement any interface
  public void FullAccess() {}     //implements interface
}


public class B
{
  private A a = new A();

  public IA GetA()
  {
    return (IA)a;
  }

  public void Func()
  {
     /* will be able to call LimitedAccess only from class B, 
        as long as everybody else only has a reference to the interface (IA). */
     a.LimitedAccess();       
  }
} 


//This represents all other classes
public class C
{
  public IA Ia;

  public void Func()
  {
     Ia.FullAccess();           // will be able to call this method
     Ia.LimitedAccess();        // this will fail compile
  }
} 

public static class MainClass
{
  static void Main(string[] args)
  {
    B b = new B();
    b.Func();
    C c = new C();
    c.Ia = b.GetA();
    c.Func();
  }
}
Run Code Online (Sandbox Code Playgroud)