简体   繁体   中英

C# - Class design & access modifiers

Given the following:

public abstract class Base
{
  // other stuff

  public static void StaticMethod()
  {
    PrivateMethod();
  }
  // here should be PrivateMethod() declaration somehow
}
public sealed class Derived: Base
{
  // other stuff

  public void InstanceMethod()
  {
    // call somehow PrivateMethod 
    PrivateMethod(); 
  }
}

I need to make use of PrivateMethod() from 2 different contexts (different assemblies). Once calling Base.StaticMethod() , and the second time by using an instance of the Derived class d.InstanceMethod(); .

I am looking for a way how to design PrivateMethod() inside the Base class. Of course PrivateMethod() should not be visible outside the Base and Derived classes.

I was thinking something about "protected static PrivateMethod() {}" but I read I should not do that...

What do you recommend guys?

  protected static void PrivateMethod() {}

Is OK (apart form the name) and does what you require. You won't need base. when calling it from Derived.

I had never heard this before, so I went looking for something that said what you described. I found this article: New Design Guideline: Avoid Protected Static . However, it only talks about protected static field.

I don't think the article actually makes a good case for what it is trying to say. Rather than just describing how protected statics can lead to complications, it uses a very simple example of the base class designer not setting the right access flags for something that should not be accessed by everyone.

That being said, there is still a point that protected static can lead to complications. Protected static means that any subclass can call a method at any time. This can lead to thread safety concerns if the method is written naively. It seems like the article was written in a way that it conveys "Don't do it" rather than "If you need to do it, be careful."

You could just call the public StaticMethod() from your derived class's InstanceMethod() ... since it indirects back to PrivateMethod() anyway. That way you can leave PrivateMethod() private. The implementation would be something like:

public abstract class Base
{
  // other stuff

  public static void StaticMethod()
  {
    PrivateMethod();
  }

  // here should be PrivateMethod() declaration somehow
  private static void PrivateMethod()
  {
    // do stuff
  }
}
public sealed class Derived: Base
{
  // other stuff

  public void InstanceMethod()
  {
    // call somehow PrivateMethod 
    StaticMethod(); 
  }
}

PS: If there is need during StaticMethod to differentiate between a public caller or a derived class caller (from InstanceMethod) it could be either passed as parameter, or determined via reflection.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM