subclass with static constructor

J

John A Grandy

Class1 : BaseClass

I only intend Class1 to have static methods. I can't make it static because
it inherits BaseClass , but I still would like it to have a static
constructor.

However, I need Class1 to invoke BaseClass constructor -- which is illegal.

Is there some way I can accomplish my goal of designing a subclass with a
static constructor that invokes the base class constructor ?
 
J

John A Grandy

Here is what I'm attempting to accomplish ( and I am agnostic as to the
implementation details ).

I have a variety of data-access functionality , meant to be accessed
statically.

Some of the data-access functionality is generic ( ExecuteNonQuery() ) but
some is database-specific ( methods which call specific stored procedures ).

All of the data-access functionality depends on a connection string.

Obviously , the connection string is different for different databases.


So, in the external world , I would like to make static calls such as :

MyDatabase1.ReadBlah( int blahId );

MyDatabase2.CreateFoo( string fooName );


My idea was for MyDatabase1 : GenericDatabase , MyDatabase2 :
GenericDatabase

Somehow MyDatabase1 and MyDatabase2 need to inform GenericDatabase of its
connection string.

My idea was that this could somehow be accomplished via static constructors.
 
J

John A Grandy

Converting over to statics is a firm requirement -- *my* firm requirement.

Instance classes and singletons is what I have presently. I don't like it.
It seemed like a good idea on a small-scale , but in a complex multi-tiered
application , it's too much extra code.


I've come up with 2 hacks ... not sure which one I prefer ....

1. in the Db class , add a protected method _Initialize( string
sqlConnectionString ) which sets the private member_sqlConnectionString

MyDatabase1 , MyDatabase2 classes' static constructors call
_Initialize( < appropriate connection string > )


2. MyDatabase1 , MyDatabase2 classes no longer inherit from Db class

change the signature of all the static methods in the Db class to include a
connection string parameter


What do you think ?
 
J

John A Grandy

Sounds like you're saying that to avoid code-duplication I'm stuck with
singletons.

I would have thought a static subclass would effectively have its own single
instance ( containing the db-specific connection string ).
 
P

Pavel Minaev

Sounds like you're saying that to avoid code-duplication I'm stuck with
singletons.

I would have thought a static subclass would effectively have its own single
instance ( containing the db-specific connection string ).

First of all, there's no such thing as a static subclass - at all.

A static class doesn't have instances, either. It has static members,
which is state, but that state is one per each app (well, AppDomain,
strictly speaking). And you want to have distinct state for every
different kind of database connection you have. In your example,
MyDatabase1 and MyDatabase2 will "share" all GenericDatabase members
between them - there are no copies of those magically created somehow.
So long as you have more than one specific connection class at the
same time, it means that static is not what you need - insisting on
using it is like insisting on using a wrench to hammer in nails -
certainly possible, but severely disadvantageous for no good reason.
 
J

John A Grandy

I don't see any reason why a language could not be designed where static
classes can inherit static classes.

In such a language , the static subclass wouldn't have a runtime base class
instance. But it's runtime copy would have all the static members,
properties, and methods of the static parent class. "private" wouldn't mean
quite the same thing in the context of static subclasses, but that doesn't
seem to be too big a syntax transgression.

Such a static subclass would have a single runtime copy ( not a one runtime
copy for itself and one for its parent ).


As far as singletons, I do see disadvantages. There are threading issues if
not designed properly, there is a slight performance hit always having to
obtain the instance, and the usage syntax is wordy ( if , like me , you like
to give meaningful names to your classes ) .

For example , which would you prefer ?

StaticSubclassSingleton.Instance.AVeryLongMethodName( <param1 value> ,
<param2 value> );

StaticSubclass.AVeryLongMethodName( <param1 value> , <param2 value );
 
P

Pavel Minaev

I don't see any reason why a language could not be designed where static
classes can inherit static classes.

In such a language , the static subclass wouldn't have a runtime base class
instance.  But it's runtime copy would have all the static members,
properties, and methods of the static parent class.  "private" wouldn'tmean
quite the same thing in the context of static subclasses, but that doesn't
seem to be too big a syntax transgression.

Such a static subclass would have a single runtime copy ( not a one runtime
copy for itself and one for its parent ).

It is certainly possible to do things that way. The point is that such
classes and their members would no longer be "static" by the
conventional definition of the word "static" (as used in C++, Java,
C#, D, and many other languages).

Besides, from a purely language design point of view, there are still
better alternatives to the problem you describe. Some languages (Java,
Scala, F#) allow you to create instances of anonymous classes that can
optionally derive from some base class. Those instances are
effectively eagerly-created singletons, and the implementation is free
to optimize storage allocation in such a way that it is no less
efficient than static.
As far as singletons, I do see disadvantages.  There are threading issues if
not designed properly, there is a slight performance hit always having to
obtain the instance, and the usage syntax is wordy ( if , like me , you like
to give meaningful names to your classes ) .

Static in C# can have performance issues, too - if you have a static
constructor in the class, then every static member invocation has to
ensure that the constructor has been called already.
 
J

John A Grandy

<<<
Still, the typical usage pattern is to store the instance into a local
variable and reference it that way, rather than typing
"SubclassSingleton.Instance" over and over again. Conversely, if you are
only using the method from the singleton once in a given block of code,
who cares how long it is, especially given that the IDE makes it nearly
the same in terms of typing as if it were simply a static method.

In any case, the question of typing has very little to do with the
question of OO design. It's not a good idea to try to contort OO design
just so you can avoid some typing. And generally, since OO design is
about code reuse, any typing you might save, you do so only in the
short-run, spending more time typing just to do the contortions you desire.

Penny-wise, pound-foolish, some might say. :)
I'm not talking about the inconvenience of extra typing.

I'm talking about readability.

I'm sure you've worked on large projects with many developers who ( despite
team-level efforts to establish standards & practices ) all write code in a
slightly different style.

A couple common patterns in team-developed projects that I find lend to poor
readability are :

1. too many lines of code that are too long to fit within a common window
width ( e.g. VS settings out of the box , 19" monitor )

If too-long code-lines are not split into multiple-lines, it is a huge pain
to constantly be scrolling to the right.

If too-long code-lines are meant to be multi-lined , it becomes an
enforcement problem ( i.e. not all devs check-in clean code ) , and there
are definitely are serious readability issues with some multi-lined lines of
code ( i.e. there are good ways to go about splitting the code ,and there
are very bad ways to go it -- trust me I've seen it )

The too-long code-lines problem is a direct outgrowth of the modern OO
standard practice first advanced by Gosling ( I think ) towards giving
meaningful "plain English" names to entities. Everything in this world is a
blance , pro/con, yin/yang, and Gosling's propagation of a coding pattern of
devising "plain English" names is not without negatives.


2. use of obscure acronyms

For example , in the project I'm working on now , sure , I could do this :

public Method1()
{
MarketDataDatabase mdDb = MarketDataDatabaseSingleton.Instance;
ApplicationDatabase appDb = ApplicationDatabaseSingleton.Instance;
PositionKeeperDatabase pkDb = PositionKeeperDatabaseSingleton.Instance;

// 100s of lines of code later ...

// line number 678
LongEntityName longEntityInstanceName =
pkDb.ObscureAndVeryLongMethodName( <param1 value> , <param2 value> , etc. );
AnotherLongEntityName anotherLongEntityInstanceName =
mdDb.ObscureAndVeryLongMethodName( <param1 value> , <param2 value> , etc. );
// etc.

}


The problem here is that someone new to the project might be resolving a bug
that's known to occur on line 678 , and they look at "mdDb" and "pkDb" and
think "what's that ?"

Sure, right-click "Go To Definition" ... but my point is that all these
niggling memory-joggers and jumping-around to gain understanding **can and
do** add-up to brain twisting inertia in a gargantuan mutli-dev project with
100s or even 1000s of classes where oftentimes even the original author of a
given section of code gets badly confused coming back months later after
numerous bug-fixes and extentions/additions/tweaks by others.

Plus , what if some other dev on the project writes similar code in some
other method like this :

public Method2()
{
MarketDataDatabase market = MarketDataDatabaseSingleton.Instance;
ApplicationDatabase app = ApplicationDatabaseSingleton.Instance;
PositionKeeperDatabase position =
PositionKeeperDatabaseSingleton.Instance;

// etc.

}

Now we've lost any sort of standardization in naming of the local instance
vars , and the confusion multiplies.


What I look to do in designing class libs is give people fewer chances to
expand the "application nomenclature" in obscure , non-congruent ,
personalized fashion.


Peter Duniho said:
I don't see any reason why a language could not be designed where static
classes can inherit static classes.

One _can_ design a programming language to be and do just about anything
the designer wants.

That's not really the point.
[...]
As far as singletons, I do see disadvantages. There are threading
issues if not designed properly,

Red herring. If there are threading issues, there are threading issues
with or without the singleton and you need to solve them either way. If
you're simply talking about the instance getter itself, well...that's
something you only have to do once, and there are numerous examples you
can follow to make sure you do it right (including simply letting the
run-time handle it for you by using a static initializer for the instance
variable).
there is a slight performance hit always having to obtain the instance,

Completely untrue. The getter will be inlined, and will be barely
different than whatever dereferencing was required internally in a static
method to accomplish your goal. There is no measurable performance
difference. That would be true with _any_ singleton vs. static class
design, but in your case with the databases involved, it's especially
true. The cost of accessing the database will completely dominate.
and the usage syntax is wordy ( if , like me , you like to give
meaningful names to your classes ) .

If you insist, you can always write static methods on the containing class
that simply delegate to the instance. Depending on the rest of the
design, you might even be able to take advantage of extension methods, and
use that syntax with an pre-existing object you know you'll always be
using with the static methods.

Still, the typical usage pattern is to store the instance into a local
variable and reference it that way, rather than typing
"SubclassSingleton.Instance" over and over again. Conversely, if you are
only using the method from the singleton once in a given block of code,
who cares how long it is, especially given that the IDE makes it nearly
the same in terms of typing as if it were simply a static method.

In any case, the question of typing has very little to do with the
question of OO design. It's not a good idea to try to contort OO design
just so you can avoid some typing. And generally, since OO design is
about code reuse, any typing you might save, you do so only in the
short-run, spending more time typing just to do the contortions you
desire.

Penny-wise, pound-foolish, some might say. :)

Pete
 
J

John A Grandy

I'm not trying to win a (non-existent) argument with you. I sincerely thank
you for your valuable insights. I already gave up on using statics.

My point is that these readability issues become problematic in large-scale
projects. And I've worked on enough large-scale projects to know that even
with the best intentions , best managers , and best teams these types of
problems always seem to re-emerge.

You might not be considering the total issue :

1. what about tight schedules, resources, etc. where code-reviews slip in
priorty ? what about devs who when supervised and reviewed follow protocol
but who when trusted to their own devices lose interest.

2. what about contractors brought in for specialized tasks with little
supervision ? and they might be off-site and on tight budgets ... ask them
to re-write their code to conform to standards ? with what $ ? the budget
is already spent. And no one else has time to do re-writes ( reason
contractor was brought in might be resources already too tight ).

3. what about transferred projects ( transferred from one in-house team to
another ; or more likely , written by an outside consultant but now in-house
; and sometimes this occurs in multiple cycles )

4. what about prima donnas who refuse to conform but who are impossible to
replace b/c of their specialized knowledge/abilities ?

5. what about copy-paste , where badly written legacy code nonetheless
propagates in the interest of saving time and/or lack of know-how and/or
laziness



Even very advanced developers when faced with adding critical functionality
to a code-base they are unfamiliar with , or with fixing a bug on a critical
time-schedule , will augment already-long methods into the 100s of lines
rather than re-factor. After all , a lot times these issue boil down to
$$$$. People don't want to spend the time to do it right because the
managers just want it done ASAP and don't appreciate/reward the extra
time/effort involved in re-factoring. Who's going to do it on their own
time ? There aren't very many True Believers in the ranks of corporate
developers. Most are in it for the money.

I've been on a number of projects where there is yards and yards of
badly-designed , badly-written , badly-factored code and no one is ever
going to fix it because from a business perspective the code is viewed as a
done-deal and the current money-flows are demanding new functionality.

And this type of thing extends outside of commercial projects. What about
JavaScript ? JS was cranked-out at Netscape under tremendous pressure
primarily for business not technological reasons , and consequently has all
sorts of crappy constructs, big bugs, confusing syntax, etc. , most of which
still haven't been fixed. The JSON requirement that object names be
enclosed in double-quotes is a result of a unfixed JS bug.


Peter Duniho said:
[...]
public Method1()
{
MarketDataDatabase mdDb = MarketDataDatabaseSingleton.Instance;
ApplicationDatabase appDb = ApplicationDatabaseSingleton.Instance;
PositionKeeperDatabase pkDb =
PositionKeeperDatabaseSingleton.Instance;

// 100s of lines of code later ...

// line number 678
LongEntityName longEntityInstanceName =
pkDb.ObscureAndVeryLongMethodName( <param1 value> , <param2 value> ,
etc. );
AnotherLongEntityName anotherLongEntityInstanceName =
mdDb.ObscureAndVeryLongMethodName( <param1 value> , <param2 value> ,
etc. );
// etc.

}

If you've got a method in your code base that is hundreds of lines long,
you've got bigger problems than typing the "Instance." every time you want
to access a singleton.

In any case, I believe I've made clear my opinion on the matter. As long
as the best argument you can come up with in favor of your proposed
(unworkable in C#) design are these red herrings or incorrect claims,
there doesn't really seem to be much else for me to offer. It sounds to
me as though you need your team to start working as a team, complete with
agreed-upon conventions to keep the code maintainable, not a new design
pattern. But you seem set on this path, and it's not my job to convince
you otherwise.

Pete
 
A

andy.johnstone

Class1 : BaseClass

I only intend Class1 to have static methods.  I can't make it static because
it inherits BaseClass , but I still would like it to have a static
constructor.

However, I need Class1 to invoke BaseClass constructor -- which is illegal.

Is there some way I can accomplish my goal of designing a subclass with a
static constructor that invokes the base class constructor ?

Does this work?

public sealed class Class1: BaseClass {
private Class1() : base() { }

// Only static methods
}

public abstract class BaseClass {
protected BaseClass() { }
}
 
A

andy.johnstone

I would have thought a static subclass would effectively have its own single
instance ( containing the db-specific connection string ).

No.. by definition a static class does not have ANY instances.
 
B

Ben Voigt [C++ MVP]

John A Grandy said:
Class1 : BaseClass

I only intend Class1 to have static methods. I can't make it static
because it inherits BaseClass , but I still would like it to have a static
constructor.

However, I need Class1 to invoke BaseClass constructor -- which is
illegal.

Is there some way I can accomplish my goal of designing a subclass with a
static constructor that invokes the base class constructor ?

Yes. Use containment, not inheritance:

public class GenericDatabaseConnection
{
protected GenericDatabaseConnection(string connectionString) {...}
}

public static class DB1
{
private sealed class DB1Connection : GenericDatabaseConnection
{
public DB1Connection() : base(db1ConnectionString) {}
}

private static DB1Connection cxn = new DB1Connection();

public static .... { cxn....(...); }
}
 
B

Ben Voigt [C++ MVP]

John A Grandy said:
I don't see any reason why a language could not be designed where static
classes can inherit static classes.

In such a language , the static subclass wouldn't have a runtime base
class instance. But it's runtime copy would have all the static members,
properties, and methods of the static parent class. "private" wouldn't
mean quite the same thing in the context of static subclasses, but that
doesn't seem to be too big a syntax transgression.

Such a static subclass would have a single runtime copy ( not a one
runtime copy for itself and one for its parent ).


As far as singletons, I do see disadvantages. There are threading issues
if not designed properly, there is a slight performance hit always having
to obtain the instance, and the usage syntax is wordy ( if , like me , you
like to give meaningful names to your classes ) .

For example , which would you prefer ?

StaticSubclassSingleton.Instance.AVeryLongMethodName( <param1 value> ,
<param2 value> );

StaticSubclass.AVeryLongMethodName( <param1 value> , <param2 value );

This can be easily solved with a property in the consumer class:

private static StaticSubclassSingleton StaticSubclass { get { return
StaticSubclassSingleton.Instance; } }
 
P

Paul

I could only read so far. The bit I got was trying to set the connection
string in the base class from the concrete derived classes. Im probably
totally confused but see if the following helps

public abstract class GenericDatabaseProvider
{
protected string connectionString;
}

public class SQLDBProvider : GenericDatabaseProvider
{
public Database1()
{
Connectionstring = ..........lookup SQL ConnStr..........
}
}

public class OracleDBProvider : GenericDatabaseProvider
{
public Database1()
{
Connectionstring = ..........lookup Oracle ConnStr..........
}
}
 
P

Paul

John,

All the reasons you state are probably the very reason to stick to standard
OOAD and standard patterns. Creating something that requires thinking outside
of the box from normal OOAD or Patterns could in essence create the very
issues you are trying to resolve.

Paul
 
I

Ignacio Machin ( .NET/ C# MVP )

Class1 : BaseClass

I only intend Class1 to have static methods.  I can't make it static because
it inherits BaseClass , but I still would like it to have a static
constructor.

However, I need Class1 to invoke BaseClass constructor -- which is illegal.

Is there some way I can accomplish my goal of designing a subclass with a
static constructor that invokes the base class constructor ?

Hi,

Unless that BaseClass is also static your derived class will not be
static, it will contains all the members of the base.

Can you use composition instead of inheritance?
In this way Case1 will have a member of BaseClass that will be
instanciated in the constructor.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top