Correct OOP Behavior or Compiler Glitch?

  • Thread starter Thread starter Kenneth Baltrinic
  • Start date Start date
K

Kenneth Baltrinic

This isn't a problem from the standpoint that its easy to work around.
However, I am very currious as to the correctness of this behavior.

I am developing an MDI application. In the application I have defined a
Toolbox class deriving from System.Windows.Forms.Form. I want only one
instance of this class to ever exist and for it to be displayable by calling
a static method of the class called Show(). To my surprise, my static
method is masking the instance (non-static) Show() method which the class
inherits from System.Windows.Forms.Form and the compiler warns me to declare
it with the 'new' modifier. Is this correct behavior? Can and should
static and non-static members mask each other? It would seem to me that
becuase reference to each are qualified differently (i.e. ClassName.Method()
vrs InstanceVar.Method()) the compiler can clearly distiguish which is being
sought and that there should never being any masking issues.

Below is an abreviated class definition for the Toolbox class that
exemplifies the issue.

public class Toolbox : System.Windows.Forms.Form
{
private static Toolbox StaticInstance = new Toolbox();

private Toolbox()
{
// Init code that builds the contents of the tool box
// from a config file.
}

//Why do I need the 'new' keyword here. Are not static and instance
members sufficiently
//distinct to be able to avoid name conflicts?
public static new void Show()
{
//Compiler Glitch? Need to cast this to a form, otherwise the
compiler thinks
//we are trying to reference a Toolbox's static Show method, i.e.
the
//method we are currently defining!
((Form)StaticInstance).Show();
}
}

--Ken Baltrinic
 
Kenneth Baltrinic said:
This isn't a problem from the standpoint that its easy to work around.
However, I am very currious as to the correctness of this behavior.

I am developing an MDI application. In the application I have defined a
Toolbox class deriving from System.Windows.Forms.Form. I want only one
instance of this class to ever exist and for it to be displayable by calling
a static method of the class called Show(). To my surprise, my static
method is masking the instance (non-static) Show() method which the class
inherits from System.Windows.Forms.Form and the compiler warns me to declare
it with the 'new' modifier. Is this correct behavior? Can and should
static and non-static members mask each other? It would seem to me that
becuase reference to each are qualified differently (i.e. ClassName.Method()
vrs InstanceVar.Method()) the compiler can clearly distiguish which is being
sought and that there should never being any masking issues.

The C# compiler can, but others may not be able to. For instance, in
Java you can do:

Thread.currentThread().sleep(5000);

which makes it look like sleep is an instance method, when in fact it's
a static method. I'd imagine that users of J# could get confused by
your class.

I don't think it's a compiler error though - from section 10.7.1.2 of
the ECMA spec:

<quote>
A method introduced in a class or struct hides all non-method base
class members with the same name, and all base class methods with the
same signature (method name and parameter count, modifiers, and types).
</quote>

There's no mention of a static method only hiding other static methods
or an instance method only hiding other instance methods.
 
Kenneth,

On the surface, I would think that it is a bug as well, or rather, it
shouldn't give you that error. However, there is a gnawing feeling deep
within me that is telling me that the compiler is correct.

Based on what you are doing though, instead of exposing a Show method,
you really should be using a singleton pattern to expose the single
instance. Then, Show would be called on that instance.

Hope this helps.
 
maybe a singleton pattern would be a better choice?

class MyClass
{
//holds the only instance of a class
private static MyClass singleInstance=null;

//private constructor. You cant explicitly create an instance of this
class
private MyClass()
{
//constructor logic
}

//static public methot creating one and only one instance of an object
public static MyClass GiveMyClass()
{
//if not created, create
if(singleInstance==null)
singleInstance=new MyClass();
//return the only instance
return singleInstance;
}
}
--


"Zeglarstwo jest koniecznoscia
zycie nia nie jest"

www.saper.infra.pl/

Saper(ek)
 
with that implementation, what holds me from creating more than one
instance? nothing. constructor is public, so I can create as many instances
as I want...

thread sagety is another thing, but I was trying to keep it as simple as I
can.

--


"Zeglarstwo jest koniecznoscia
zycie nia nie jest"

www.saper.infra.pl/

Saper(ek)
 
Saper(ek) said:
with that implementation, what holds me from creating more than one
instance? nothing. constructor is public, so I can create as many instances
as I want...

Which implementation is that? Each implementation on that page have a
private constructor, and no other constructors. If I've made a mistake
on the page, please point it out precisely.
thread sagety is another thing, but I was trying to keep it as simple as I
can.

In what way is your version simpler than:

public class Singleton
{
static Singleton instance=new Singleton();

Singleton()
{
}

public static Singleton GetInstance()
{
return instance;
}
}

?

(You can optionally have a static constructor in there which just
prevents the compiler from adding the beforefieldinit flag, too.)
 
Why not implement the Singleton as


// .NET Singleton
sealed class Singleton
{
private Singleton() {}
public static readonly Singleton Instance = new Singleton();
}


mucho simpler :D
 
Cant get simpler than that :D Static initialisztion is guranteed thread
safe by the runtime. It fixes old workworunds (that you do with locking in
non managed code) on other runtimes which dont have such gurantees.

readonly means its set once and only once.

Here you have both features of the singleton design pattern.
1. Well known access point to the instance (via static Instance method)
2. one guranteed instance and no more. (via readonly)

So, you would call the above with the static interface (the wellknown access
point) Singleton.Instance.SomeFeatureHereBlahSmerdyHerdyBorkBork

How simpler do you want it?



news.microsoft.com said:
Why not implement the Singleton as


// .NET Singleton
sealed class Singleton
{
private Singleton() {}
public static readonly Singleton Instance = new Singleton();
}


mucho simpler :D

Jon Skeet said:
Which implementation is that? Each implementation on that page have a
private constructor, and no other constructors. If I've made a mistake
on the page, please point it out precisely.
as
 
news.microsoft.com said:
Why not implement the Singleton as


// .NET Singleton
sealed class Singleton
{
private Singleton() {}
public static readonly Singleton Instance = new Singleton();
}
mucho simpler :D

Yes, that is another option too. (You *can* get simpler in terms of the
code, by getting rid of the private modifier, but that's a different
discussion.)

As I write on my page:

<quote>
Note that all of these implementations also use a public static method
GetInstance as the means of accessing the instance. In all cases, the
method could easily be converted to a property with only an accessor,
with no impact on thread-safety or performance.
</quote>

Not all of them can be converted to public readonly variables (the
fully lazy instantiation one, which allows other static methods to be
called without the singleton itself being created) but I think I'd
generally prefer to leave it as a property or a method anyway, just in
case the implementation needs to become smarter later on.

I shall fix the page to use readonly variables where possible, and to
make the class explicitly sealed, both of which are good things to do.
 
As Jon mentioned, you don't get lazy creation this way. That's fine if you
are sure you want your instance to be made as soon as the JIT gets to your
class. But in interests of performance, using a method or a property will
delay instantiation until the object is actually needed.

Niall

news.microsoft.com said:
Why not implement the Singleton as


// .NET Singleton
sealed class Singleton
{
private Singleton() {}
public static readonly Singleton Instance = new Singleton();
}


mucho simpler :D

Jon Skeet said:
Which implementation is that? Each implementation on that page have a
private constructor, and no other constructors. If I've made a mistake
on the page, please point it out precisely.
as
 
Niall said:
As Jon mentioned, you don't get lazy creation this way. That's fine if you
are sure you want your instance to be made as soon as the JIT gets to your
class. But in interests of performance, using a method or a property will
delay instantiation until the object is actually needed.

In fact, it *doesn't* make sure that your instance is made as soon as
the JIT gets to your class - the JIT can choose to run the type
initializer of a class with beforefieldinit *later* than it would under
other circumstances. For instance, it could not bother running it at
all, ever, if the class's static fields are never touched - even if the
class is instantiated! It's all very odd...

(In practice, I'm sure it *does* always mean it's initialized earlier -
I'm only talking in theory here.)
 
Hmm, sounds like the same kind of mysterious workings as what makes the GC
decide to run... Maybe I should do some research and write a book:
"Mysteries Revealed: The Secrets of the Pyramids, Inner Happiness and .Net
Internals".

Niall
 
Second try. This of course is not the Singleton pattern described by the
Gang of Four since it is missing a getter and hence a level of
indirection.
The Singleton pattern supports flexibility of design so that you can
change the design to support "a variable number of instances."

Regards,
Jeff
 
Back
Top