views:

48

answers:

4

Maybe I should just make this a public member, but I keep thinking it should be a constant.

SCENARIO

I have forms I'm rendering into PDFs (using iTextSharp). In code, the forms themselves all inherit a base class (OrderForm). Within OrderForm, there are a list of constants that I use for measurements when aligning things for the PDF rendering, such as LEFT_MARGIN, etc. These constants are used in several functions to determine where things go.

All the forms are virtually identical as they are comprised of the same components (header, address boxes, items, etc). However, the layout of the forms differ slightly... on one form, the address box is an inch further to the right (to fit in the envelope window my employer uses).

ISSUE

Rather than create a slew of constants for each margin, padding, blah blah for each form in the base class, eg: PURCHASE_ORDER_LEFT_MARGIN, INVOICE_LEFT_MARGIN, etc, wouldn't it be better to create an overridable LEFT_MARGIN that can be set in the "inheritee" [sic] object? My reasoning is that it is a constant that will not change within that object, only form to form, yet the renderings in the base class will remain relative to whatever that constant is.

I know I could simply create a public member and set its value, but I'd like to know the right way to go about this.

Thanks.

+3  A: 

Constants are implicitly static (Shared).

Use a Readonly Property instead, and then you can choose to override it whenever or wherever need be.

A quick example ....

Class BaseClass

    ' Assume this field is set with a value from somewhere else'
    Private _leftmargin As Integer

    Overridable Readonly Property LEFT_MARGIN  As Integer
        Get
            Return _leftmargin
        End Get
    End Property
End Class

Class DerivedClass1
    Inherits BaseClass

    Overrides Readonly Property LEFT_MARGIN  As Integer
        Get
            Return 5 'specialized case for this class'
        End Get
    End Property
End Class

Class DerivedClass2
    Inherits BaseClass

    'uses base class LEFT_MARGIN'

End Class
John K
hm.. i kind of like this idea
Jason
i ended up going with this solution. thanks!
Jason
+1  A: 

What you want is a regular property ... Any value that changes is not a constant ... :)

Noon Silk
that's the rub... i don't want it to CHANGE, per se. As in, it can't be modified, just set at the object declaration
Jason
You can achieve that by having only 'get' defined in the property, and set it only in the constructor (via the backing variable directly). I can't remember if .NET allows you do leave the setting of const variables until the constructor is called (I suspect not, because they're static I believe), Java has `final` variables, which can do this). Anyway, the first method I suggested will work.
Noon Silk
A: 

What you can do is to use methods instead of constants. At the base class the method will return the value of the constant as it is now.

Inheriting class can provide a new value for the "constant" by overriding the corresponding method.

Itay
+2  A: 

Constants are compiled as literal values. If you have this (C#) source code:

public static class MyStringTestClass
{
    // Fields
    public const string ConstString = "Const String";

    public void TestMethod()
    {
        string sc = MyStringTestClass.ConstString;
        SomeOtherFunction(sc);
    }
}

then the compiler will produce this:

public static class MyStringTestClass
{
    // I'm not 100% sure if this declaration is removed as well...
    public const string ConstString = "Const String";

    public void TestMethod()
    {
        // ...but I know for sure that it will be removed
        // everywhere it's used - including other assemblies!
        string sc = "Const String";
        SomeOtherFunction(sc);
    }
}

As you see, "ConstString" is completely GONE and it's literal value is inserted everywhere.

So use the VB.net equivalent of a ReadOnly Virtual Property (I think "virtual" is called "Overridable" in VB.net?) and override it.

Michael Stum
this is interesting. i didn't know this. i guess it makes sense that i can't do that then.
Jason