Private Constant Encapsulation

I'm just wondering if I have a persistent attribute, can I set a public property to encapsulate it?

eg.

private const int DEFAULT_CHARGE = 200;
public int default_charge
{
     get { return DEFAULT_CHARGE; }
}

      

I don't get any errors, but if something is persistent, I don't quite understand the logic behind why we are encapsulating it. I really want to understand why this:

  • right wrong
  • why do this?
  • advantages?
+3


source to share


5 answers


It is important to know that constants are built into the compiler. This means that these two examples lead to the same program:

private const int DEFAULT_CHARGE = 200;
public int default_charge
{
     get { return DEFAULT_CHARGE; }
}

      

The same as after compilation:

public int default_charge
{
     get { return 200; }
}

      

As you can see, after compilation, the link to DEFAULT_CHARGE

is lost. This is important to remember for solutions where you reuse the same constants across multiple projects.



Let's say you are using DEFAULT_CHARGE

both public const

LibA and LibB. The project manager tells you to change the value from 200 to 300. Intuitively, you go to LibA where it is DEFAULT_CHARGE

defined, you change it to 300, and then you recompile and deploy only LibA.

As a result, LibA now uses the new value 300, but LibB continues to use the old value 200 because the constant was baked into the DLL at compile time.

The reason you can encapsulate a constant is because you can change the value more easily. Requirements change over time. A value DEFAULT_CHARGE

that is constant today may need to be replaced with a configuration value in the future.

By encapsulating the constant, you also prevent the problem I just explained. If LibA and LibB (and LibX, LibY, LibZ, ...) depend on encapsulation, you only need to recompile and deploy LibA to set the board as default in all dependent programs.

+1


source


Even if something is persistent, you can still control how it returns to the caller. If you have a double variable that is stored to 5 decimal places, you may want to return the value to the caller in 2 decimal places. Encapsulation helps you get control over your fields.

So you may need to encapsulate a constant field like this



private const double DEFAULT_CHARGE = 200.12345;
   public int default_charge
 {
 get { return Math.round(DEFAULT_CHARGE,2); }
 }

      

+1


source


You might want to implement interface

, abstract class

etc .:

   public interface IChargable {
     int default_charge {get;}
   }

   public class MySimpleChargable: IChargable {
     private const int DEFAULT_CHARGE = 200;

     public int default_charge {get { return DEFAULT_CHARGE; }} 
   } 

      

You can implement such a construct as a stub:

Initial value:

   // Version 1.0
   public class MyChargable {
     private const int DEFAULT_CHARGE = 200;

     //TODO: implement (rare) "some condition" case
     public int default_charge {get { return DEFAULT_CHARGE; }} 
   } 

      

Further:

   // Version 1.1
   public class MyChargable {
     private const int DEFAULT_CHARGE = 200;

     public int default_charge {
       get { 
         if (some condition)
           return SomeComputation();

         return DEFAULT_CHARGE; 
       }
     }  

      

+1


source


It depends on your requirements.
In general, properties are meant to encapsulate whatever get / set logic you want, even computed values ​​or constants.
In my opinion public property returning the value of a private constant is good from an architectural point of view, in which case someone using your code doesn't know that it is working with a constant at all, i.e. it abstracts from your implementation, and that well. If you choose to make it not a constant but a custom value, then you won't expose it to the library consumer, you just do it like this:

// private const int DEFAULT_CHARGE = 200; <-- is not used anymore

public int DefaultCharge
{
    get { return SomeSortOfFileOrDatabaseConfiguration.DefaultCharge; }
}

      

or even

public int DefaultCharge
{
    get
    {
        return CurrentUser.PersonalSettings.DefaultCharge; 
    }
}

      

which makes this code rely on the personal preferences of the users without telling anything to its clients.

This is the main advantage. It's all about encapsulation and abstraction.

But please use the correct name for the properties - it should be public int DefaultCharge

, and take a look at Jeroen Mostert's comment about permanent insertion.

0


source


As far as I know, you can create public access to a private constant without issue.

You must create an accessor to a constant when:

  • You need to add additional logic to the receiver, for example, return it by format in some way or by a different value if a condition applies.
  • Your constant is part of a namespace that is used as a library for another namespace, because if you compile the namespace in which the constant exists, the dependent namespace will only remember the old value of the constant as determined during compilation.
0


source







All Articles