How to hide a method so that it is not called by programmers, but is still used in code?

I have a class called Ship and a class called Lifeboat

Lifeboat is inherited from Ship.

The ship contains a method called Validate() , which is called before saving and has an abstract method called FurtherValidate() , which it calls from Validate. The reason for this is that when you call validate on the base, it also validates the class that inherits. So we have

 public class Ship public bool Validate() { //validate properties only found on a ship FurtherValidate(); } public abstract bool FurtherValidate(); 

So Lifeboat has

 public override bool FurtherValidate() { //validate properties only found on a lifeboat } 

This means that anyone who implements Ship must also provide their own verification for their class, and they are guaranteed to be called up for storage as a base ship. Validate() , which in turn calls an inherited check.

How can we do this, so we still force the inherited classes to implement FurtherValidate() , but FurtherValidate() never be called by the programmer. You can currently call Lifeboat.FurtherValidate() , and I want to somehow prevent this.

+4
source share
9 answers

The exact scenario that you are describing is not possible. You can restrict access to the FurtherValidate method only to derived classes using the protected access modifier. You can also limit it to only classes in a single assembly using the internal modifier, but it will still allow the programmer to write a derived class to call the Next Step function at any time. The use of both protected and internal combinations of the two really means that they are limited to derived classes or classes defined in the same assembly.

Using the [EditorBrowsable] attribute is an IDE trick that will hide the method from IntelliSense (unless another programmer has included the correct parameters in VS). This will effectively prevent most people from calling him (if they do not see him, he does not exist).

You could achieve this by using reflection to ask who your caller is, but I think the cost of doing this will be too high compared to the benefits.

+4
source
 protected abstract bool FurtherValidate(); 

only the ship and the lifeboat can see it now.

EDIT: The lifeboat must be able to see this. How can he redefine FurtherValidate when he cannot even see it. I would rename it to ValidateCore , the β€œCore” part (for me) implies that it cannot be called without a good reason.

I do not think it is easy to make it abstract, but not visible. You must have some faith in your lifeboat;)

+7
source

Short answer: you cannot hide the received method from the class that outputs it. However, you can reorganize your code to achieve what you are trying to achieve:

 public class Ship { public virtual bool Validate() { //validate properties only found on a ship return true; } } public class Lifeboat : Ship { public override bool Validate() { base.Validate(); // lifeboat specific code return true; } } 
+7
source

The simplest answer is to make the method secure. This allows the heirs to call it, but does not make it publicly available. However, there is nothing to stop the inheriting classes changing the method for the public.

I would be more likely to remove the entire NextValidate method, and any inheriting classes will override Validate by calling base.Validate () if they wish. This allows any class that inherits from the ship to have a greater degree of control over the verification method.

+3
source

protected is the right approach. But in another situation, you can use the editorbrowsableattribute , which will hide the method from intellisense. You can still call it, but it slows down the work of developers to cause something that can explode the program, and usually forces them to read your giant warning comments.

+2
source

Providing protection, not public, will at least prevent the invocation of external objects.

+1
source

I see the smell of code here, since Validate is not part of the functional responsibility of the ship. In other words, I think maybe you are trying to solve the problem using inheritance, when perhaps this is not the best solution. Try reformulating the validation logic so that you introduce your verification into the class. This will make sense from the point of view of the Ship domain object, since the ships do not check themselves, they are checked from the outside. If you want to forcefully establish that there must be a validator, you can throw an exception if the property is null.

 protected IValidator FurtherValidation { private get; set; } public bool Validate() { //validate properties only found on a ship if (FurtherValidation == null) throw new ValidationIsRequiredException(); if (!FurtherValidation.IsValid(this)) // logic for invalid state } 
+1
source

You can mark a method as protected so that only inheriting classes can access it. This does not stop the heirs from exposing the method to another public method, but usually this is not a serious problem.

0
source

Maybe you can try a private modifier

-1
source

All Articles