The object is dialogue, so ShowDialog should be used at all times, it
makes no sense to call Show. On top of that I overloaded ShowDialog to
initialize the title and prompt in the InputBox, so, in fact I would
like to hide the base ShowDialog as well.
The suggestion for using composition is likely to be a reasonable one
here. It's true that for Control-derived classes this often is
impractical, but for a dialog form class, there's so little likelihood to
need for the code that creates your instance to treat the instance as
anything but the class you've defined, that you may not run into any
problems at all with composition. And in fact, given the apparent express
desire on your part that the instance _never_ be treated as anything other
than your defined class, this may in fact be the _most_ desirable approach.
If you really want to inherit a Form class rather than compositing it, you
could override the OnShown() method and do your initialization there,
based on some properties you expose in your derived class. You could even
allow those properties to affect the state of the form once it's been
shown (depending on how you implement the properties, it could even be
easier to allow that than to not allow it).
At the same time in the OnShown() method, you can check to see if the form
was shown modally, and throw an exception if it was not.
Those techniques address both issues without requiring you to be able to
hide the original Show() or ShowDialog() methods.
Once again, I disagree with the hard-line definitions of OOP. I see no
philosophical reason to disallow changing access modifiers on base
methods,
It's been explained to you. It's unfortunate that you disagree with the
explanation, but it's a valid, correct explanation nonetheless.
especially in this case where the base is a general purpose class and
the derived is a specialization of the base.
Actaully, the fact that the base _is_ a general purpose class is what
makes it so important for the original method to not be able to be changed.
But I guess that's just me. The argument that there is nothing stopping
the user from casting to Form and calling Show is, in this case,
invalid, kind like saying, in C++ that you can change the value of a
reference, sure you can, but who in their right mind ever would.
I don't understand the comparison to the C++ situation of changing the
value of a reference. It's nothing like this situation. It's not clear
you understand this, but keep in mind that a reference in C# is not the
same as a reference in C++. It's more like a pointer in C++.
The basic issue, as was explained before, is that once you've created an
instance of your class that inherits Form, you can pass the reference to
that instance to any other code that accepts a type compatible with your
class. In particular, you can pass your instance to anything that accepts
a Form, and that's perfectly legal.
More importantly, it's not just legal, it's extremely common in an OOP
environment and is in fact a key feature around which OOP is built. One
of the key elements of OOP is being able to not worry about the actual
type of the instance of an object, but rather to treat it as whatever
minimally-derived type is appropriate in the given context. It should not
be necessary, and is often impossible, for code using an instance via a
less-derived type to know anything about the more-derived types of the
class.
So, say you create your class and then pass it to something that only
knows about the base class. Say then that code calls the base class
method that you tried to hide or overload. Now all that hard work you
went to in order to try to hide the methods was for naught. Because your
class _is_ still a Form, anything that treats it as a Form will always
have access to the things in the Form class, no matter what you do. Not
only is this a useful thing, a lot of what makes OOP work just wouldn't
work right without it. It would break the whole idea of abstraction if
you could hide methods inherited in derived classes from code that knows
only about the base classes.
Now, for what it's worth, there are OOP environments in which you have a
little more control. You still can't hide a method, but you can ensure
that your code always gets called, because the language has _only_ virtual
methods. For example, Java. This way, you could implement your own
ShowDialog() overload, and throw exceptions from the Show() and original
ShowDialog() methods. You still can't stop someone from writing code that
calls those methods, but you can make it impossible for them to use your
class when they do so.
Anyways, as for this class, the purpose of hiding the methods is for
completeness, no one will ever use them and it's kind of an annoyance to
see them in intellisense.
Well, the compositing approach will solve the Intellisense issue. I'm not
sure, but I suppose it's possible there's a code attribute you could apply
that will hide the methods in Intellisense as well (but of course that
would only have an effect when you're dealing with an expression that is
your derived type).
Frankly, I think that concerns about what is shown in Intellisense is one
of the worst possible reasons to complain about some specific aspect of
OOP design. There are quite a lot of subtle disagreements regarding the
"best" or "appropriate" way to do things in OOP, but I don't think any
serious disagreement could be based on something so trivial. If you don't
like the way Intellisense presents the information, then the answer to
that is to argue in favor of trying to change the way that Intellisense
works, rather than complaining about fundamental aspects of the language
design.
Pete