为什么没有“外部”访问修饰符?

3

也许我有所遗漏,但 C# 应该为方法提供一个外部访问修饰符,对其他类公开方法,而该方法不能被其自身调用,这不是很有用吗?

比如,对于执行锁定的公共方法,此修饰符可确保锁定不会在类内部重新进入,这不是很方便吗?


有一个 extern 关键字,但它不是用于你所描述的。http://msdn.microsoft.com/en-us/library/e59b22c5%28v=vs.80%29.aspx - Nobody
9
只有具备多重人格障碍的程序员才会觉得这有用。如果想要让类无法访问某些方法,可以将这些方法放入另一个类中。面向对象编程的设计理念是,类应该能够访问和控制其内部包含的方法和数据。 - John Alexiou
4个回答

8

没有必要这样做。访问控制用于限制来自不受信任客户端代码的成员的访问。

请记住,在面向对象编程中,一个类代表一个自治、自包含的代码单元,并被隐含地认为是自洽的。

如果您不能信任自己类中的代码不会导致重入,那么您还能信任什么呢?使用语言特性来防范每种可能的情况是不切实际的;有时候,作为开发人员,确保自己的代码正常工作只能靠自己 :)


5

使用显式实现的接口方法可能是最接近你想要的东西。当然,如果一个类将this强制转换为接口类型仍然可以在自身上调用它们。


其实,我认为其他答案更好。本来我想发发牢骚,说你不应该需要这种行为,但是想出聪明的解决方案的诱惑力太大了。 - siride
ProgressIProgress接口是一个很好的使用示例。IProgress<T>.Report是一个私有成员,因此创建Progress<T>类的任何人都看不到Report()方法,但是所有使用IProgress<T>接口的消费者都可以调用Report()方法进行回调。 - Scott Chamberlain

3
我认为这并没有什么用处。没有范式定义它的需求。
在你的例子中:即使有"external"关键字,你如何确保锁不能在外部重新进入而没有释放?
类之间有合同,而且类总是与自身有一个合同。我认为没有关键字可以帮助避免这种编程错误。在这个特定的例子中,类应该根据其使用级别适当地实现锁定。

我不知道,我认为能够澄清代码意图并确保特定行为的语法通常是一件好事,这就是为什么我们有像readonly关键字这样的东西。一个类与自身达成“契约”也没有任何理由。 - Homde

0

这是我的TypeScript笔。

或许这对任何人来说都有用,可以描述可以通过外部访问修饰符解决的问题。

codepen

class ExternalUser {

  private static _time: number = 0;
  position: {x: number, y: number} = {x: 0, y: 0};

  constructor () {
    setInterval(this.bind(this.tick), 100);
  }

  external static set time(val: number) {
    ExternalUser._time = val;
  }

  static get time(): number {
    return ExternalUser._time;
  }

  private tick() {
    let someRandomThing = Math.random() > 0.95;
    if (someRandomThing) {
      ExternalUser.time += 100;// throws error, because set time is external
    }
    this.position={x: 10 * ExternalUser.time, y: ExternalUser.time * 10};
  }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接