| Printable Version
New Modifiers in C#
By ZIAD SALLOUM
If you come from C++ or Java background to C#, no wonder that you will notice
some strange keywords introduced to this new language.
The first reaction will be what are these things for and why were they added
?
Specially that, till now people were able to develop programs using the
existing languages without problems.
Among the set of new keywords added to C# there are new and
override modifiers.
Although new may not seem that new to you , however its usage as
method modifier is completely new.
The new modifier
Similarly to C++ , C# allow redefinition of inherited methods in the derived
classes at the cost of hiding the inherited ones.
Although hiding is not an error, but it does cause the compiler to issue a
warning. To suppress this warning you have to include the new modifier in
the derived method.
The real benefit of this feature is to be sure that you intentionally want to
hide the base method and this did not happen by accident or misspelling.
Conversely, if you declare a method as new and it does not really hide a base
method, the compiler will also issue a warning, that can be suppressed by
removing the new modifier.
Consider the following example :
|
public class baseHello{ |
|
| |
public void sayHello(){ |
| |
System.Console.WriteLine("base says hello"); |
| |
} |
|
|
} |
|
|
| |
|
|
|
class
derivedHello:BaseHello{ |
| |
public void sayHello(){ |
| |
|
System.Console.WriteLine("derived says hello"); |
| |
} |
|
|
} |
|
|
The preceding code will compile fine but the compiler warns you that method
derivedHello.sayHello() hides the method baseHello.sayHello() :
warning CS0114: 'derivedHello.sayHello()' hides inherited member
'baseHello.sayHello()'. To make the current method override that implementation,
add the override keyword. Otherwise add the new keyword.
As the warning suggest it is preferable to use new like the following.
|
class
derivedHello:BaseHello{ |
|
| |
new public void sayHello(){ |
| |
System.Console.WriteLine("derived says hello"); |
| |
} |
|
|
} |
|
|
The override modifier
As you certainly know, every object oriented language implements polymorphism
which is summarized by having multiple implementation for the same
interface.
While all methods in Java are virtual by default, C++ and C# require clearly
defining a method as virtual , by using virtual modifier in C++ and C# or
abstract modifier in C# only (abstract is equivalent to pure virtual in
C++ : virtual type methodName(some params) = 0; )
In order to give a different version for the same method it suffice to derive
the base class and redefine the virtual method using same name and signature,
but with different body, plus the override modifier. This may seem
annoying at the beginning specially that C++ and Java developers did not have to
do that. However experience with large projects has shown that lots of runtime
problems occur when some modifications were needed in the virtual base method
signature ,which necessarily require the same modification in all the derived
classes that give their own version.
Look at this Java example :
|
public class baseHello{ |
|
| |
public void sayHello(){ |
| |
System.out.println("baseHello says HELLO"); |
| |
} |
|
|
} |
|
|
|
public class derivedHello extends
baseHello{ |
| |
public void sayHello(){ |
| |
System.out.println("derivedHello says HELLO"); |
| |
} |
|
|
} |
|
|
In the above example the class derivedHello inherits and redefines the method
sayHello() from baseHello class.
Now suppose that at some time in the project the designer find out that the
sayHello() method should take a String parameter .
The change in the baseHello will be as follows
|
Public class baseHello{ |
| |
public void sayHello(String name ){ |
| |
System.out.println("baseHello says HELLO to "+name); |
| |
} |
|
|
} |
|
|
Now the base class is modified and still the hard work to do is to modify all
the derived classes that could be in dozens . Failing to modify one derived
class will result in a behavior different than expected as the following code
will show:
|
public class TestHello{ |
| |
public static void print(baseHello hello){ |
| |
hello.sayHello("TestHello"); |
| |
} |
|
| |
|
|
| |
public static void main(String[] args){ |
| |
|
baseHello baseH= new baseHello(); |
| |
|
derivedHello derivedH= new derivedHello(); |
| |
|
print(baseH); |
| |
|
print(derivedH); |
| |
} |
|
|
} |
|
|
Running the TestHello class will result in two identical strings
baseHello says HELLO to TestHello
baseHello says HELLO to TestHello
The reason is because you failed to change the derivedHello class to be
conform to the baseHello class so the latter is used when
hello.sayHell("TestHello") is called.
Because the java compiler does not have any idea that the sayHello() in
derived class is intended to override the sayHello(String name) in the base
class , it does not complain about it and considers it as a new method defined
only in the derived class.
After exposing the problem, here is what C# offers to solve the problem.
Every method that must override a virtual base method must be declared with
override modifier. The same example applied to C# becomes
|
public class BaseHello{ |
| |
virtual public void sayHello(string name){ |
| |
System.Console.WriteLine("BaseHello says hello to
{0}",name); |
| |
} |
|
| |
|
|
|
class
DerivedHello:BaseHello{ |
| |
override public void sayHello(){// different
signature |
| |
|
System.Console.WriteLine("DerivedHello says hello"); |
| |
} |
|
|
} |
|
|
The compilation of the example will result the following error :
error CS0115:’DerivedHello.sayHello()': no suitable method found to
override
Telling the method sayHello() in DerivedHello which is intended to override
sayHello(String name) in BaseHello has different signature than its base
method.
In such way no matter who many times a class is derived it is always possible
to detect difference in methods name and signature at compile time.
Conclusion
As a conclusion , you have noticed that new and override modifiers have a key
role in preventing runtime flaws and sparing hours of
debugging. |