471,315 Members | 2,262 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 471,315 software developers and data experts.

new vs override - a practical example

Did anyone EVER come across the need to use "new" in a method
declaration (breaking with inheritance / versioning)? Allthough I know
what it does and how it is used I really have a hard time to make up a
usefull real life scenario for it. Maybe you can give a practical
example from a real life?
Nov 29 '05 #1
21 1941
Let's say you are inheriting from a class you did not write. It has a Clear
method that is not declared as allowing it to be overridden. So there is no
way for you to override it. You would have to write a method called Clear2
or something.
So, instead you use 'new' to just have your own Clear method that can be
called on that object. That also means you can't call the original version
without casting to the base class.

"bonk" <sc******************@gmx.de> wrote in message
news:On**************@TK2MSFTNGP10.phx.gbl...
Did anyone EVER come across the need to use "new" in a method declaration
(breaking with inheritance / versioning)? Allthough I know what it does
and how it is used I really have a hard time to make up a usefull real
life scenario for it. Maybe you can give a practical example from a real
life?

Nov 29 '05 #2
Marina schrieb:
Let's say you are inheriting from a class you did not write. It has a Clear
method that is not declared as allowing it to be overridden. So there is no
way for you to override it. You would have to write a method called Clear2
or something.
So, instead you use 'new' to just have your own Clear method that can be
called on that object. That also means you can't call the original version
without casting to the base class.

"bonk" <sc******************@gmx.de> wrote in message
news:On**************@TK2MSFTNGP10.phx.gbl...
Did anyone EVER come across the need to use "new" in a method declaration
(breaking with inheritance / versioning)? Allthough I know what it does
and how it is used I really have a hard time to make up a usefull real
life scenario for it. Maybe you can give a practical example from a real
life?


Sorry, that was not quite what I was looking for, maybe I should be more
specific. It is clear to me that I have to use "new" to redefine a
mehtod that doesn't have virtual in its declaration. I was more looking
for a practical example for when I would prefer "new" INSTEAD of
"override" to hide the VIRTUAL mehtod of the baseclass I derived from:

class A
{
public virtual void DoIt(){}
}
class B : A
{
public /*override (or) new (with or without) virtual*/ void DoIt() {}
}
class C : B
{
public /*override (or) new*/ void DoIt()
}
Nov 29 '05 #3
bonk wrote:
Marina schrieb:
Let's say you are inheriting from a class you did not write. It has a
Clear method that is not declared as allowing it to be overridden. So
there is no way for you to override it. You would have to write a
method called Clear2 or something.
So, instead you use 'new' to just have your own Clear method that can
be called on that object. That also means you can't call the original
version without casting to the base class.

"bonk" <sc******************@gmx.de> wrote in message
news:On**************@TK2MSFTNGP10.phx.gbl...
Did anyone EVER come across the need to use "new" in a method
declaration (breaking with inheritance / versioning)? Allthough I
know what it does and how it is used I really have a hard time to
make up a usefull real life scenario for it. Maybe you can give a
practical example from a real life?


Sorry, that was not quite what I was looking for, maybe I should be more
specific. It is clear to me that I have to use "new" to redefine a
mehtod that doesn't have virtual in its declaration. I was more looking
for a practical example for when I would prefer "new" INSTEAD of
"override" to hide the VIRTUAL mehtod of the baseclass I derived from:

class A
{
public virtual void DoIt(){}
}
class B : A
{
public /*override (or) new (with or without) virtual*/ void DoIt() {}
}
class C : B
{
public /*override (or) new*/ void DoIt()
}

I use it from time to time to make my coode more readable:

class AImp{}
class BImp: AImp{}

class A
{
protected AImp Pimpl{ get; }
}

b uses a BImp
class B : A
{
private new BImp Pimpl{ get; }
}

so inside of B intead of writing ((BImp)Pimpl).DoIt(), I can use
Pimpl.DoIt();

HTH,
Andy
----
To email me directly, remove the N*o*SPA*M part below:
xmenN*o*SPA*M40@gmN*o*SPA*Mx.net
Nov 29 '05 #4
Ok. You are writing a system using martin.dll which exposes a useful class
called Employee ...

public class Employee {

decimal salary;

...

public decimal Salary {get{...} set{...}}
...

public decimal GetPayAmount() {
return this.salary / 12;
}

}

(well not that useful but ...)

Your company wants to start paying weekly. You do not have the source for
martin.dll, so how do you change the GetPayAmount() value?

public class Employee2 : Employee {

public new decimal GetPayAmount() {
return this.Salary/52;
}

}

Any clearer?

"bonk" <sc******************@gmx.de> wrote in message
news:ub****************@TK2MSFTNGP09.phx.gbl...
Marina schrieb:
Let's say you are inheriting from a class you did not write. It has a
Clear method that is not declared as allowing it to be overridden. So
there is no way for you to override it. You would have to write a method
called Clear2 or something.
So, instead you use 'new' to just have your own Clear method that can be
called on that object. That also means you can't call the original
version without casting to the base class.

"bonk" <sc******************@gmx.de> wrote in message
news:On**************@TK2MSFTNGP10.phx.gbl...
Did anyone EVER come across the need to use "new" in a method declaration
(breaking with inheritance / versioning)? Allthough I know what it does
and how it is used I really have a hard time to make up a usefull real
life scenario for it. Maybe you can give a practical example from a real
life?


Sorry, that was not quite what I was looking for, maybe I should be more
specific. It is clear to me that I have to use "new" to redefine a mehtod
that doesn't have virtual in its declaration. I was more looking for a
practical example for when I would prefer "new" INSTEAD of "override" to
hide the VIRTUAL mehtod of the baseclass I derived from:

class A
{
public virtual void DoIt(){} }
class B : A
{
public /*override (or) new (with or without) virtual*/ void DoIt() {}
}
class C : B
{
public /*override (or) new*/ void DoIt()
}

Nov 29 '05 #5
Hi Andrew,

Check out my article, it might be helpful.

http://www.developersdex.com/gurus/articles/739.asp

Happy Coding,

Stefan
C# GURU
www.DotNETovation.com

"You always have to look beyond the horizon and can never be complacent
-- God forbid we become complacent."

Jozef Straus

*** Sent via Developersdex http://www.developersdex.com ***
Nov 30 '05 #6
bonk wrote:
Did anyone EVER come across the need to use "new" in a method
declaration (breaking with inheritance / versioning)? Allthough I
know what it does and how it is used I really have a hard time to
make up a usefull real life scenario for it. Maybe you can give a
practical example from a real life?


Sure, any static method you want to give different behavior in a
derived class.

Or as others said: you want to specify a different method in a derived
class and the method isn't virtual. A good example why you need that is
in the silly collection classes in .NET, they all don't have a virtual
Add() method for example. If you want to perform additional code in the
Add method, you can only do that if you use 'new'.

FB

--
------------------------------------------------------------------------
Get LLBLGen Pro, productive O/R mapping for .NET: http://www.llblgen.com
My .NET blog: http://weblogs.asp.net/fbouma
Microsoft MVP (C#)
------------------------------------------------------------------------
Nov 30 '05 #7
I've used it to add accessors to a property, when a base class has a
property that's read-only, but I want it to be read-write in a derived
class. Unfortunately I have to create an intermediate class to do it:

// read-only Height is fine for most classes derived from B...
abstract class B {
abstract int Height { get; }
}

// but for D it has to be read-write
abstract class Bhack : B {
// implement B.Height by calling into the derived class
override int Height { get { return HackGetHeight(); } }
protected abstract int HackGetHeight();
}

class D : Bhack {
// answer the call from Bhack.Height
protected sealed override HackGetHeight() { return this.Height; }
// and replace the old property with a new one
new int Height { get { ... } set { ... } }
}

Jesse

Nov 30 '05 #8
So, instead you use 'new' to just have your own Clear method that can be
called on that object. That also means you can't call the original version
without casting to the base class.


This is not true.

class Foo
{
public int f() { return 0; }
}
class Bar: Foo
{
public new int f() { return 1; }
}
class Test
{
public static void Main()
{
Bar bar = new Bar();
System.Console.WriteLine("bar.f()={0}", bar.f());
Foo foo = bar;
System.Console.WriteLine("foo.f()={0}", foo.f());
}
}
Many of the replies in the threads tries to tell you to use "new" to do
override without virtual. The above is why that doesn't work.

--
Helge Jensen
mailto:he**********@slog.dk
sip:he**********@slog.dk
-=> Sebastian cover-music: http://ungdomshus.nu <=-
Nov 30 '05 #9


jm*****@gmail.com wrote:
I've used it to add accessors to a property, when a base class has a
property that's read-only, but I want it to be read-write in a derived
class. Unfortunately I have to create an intermediate class to do it:


How about:

class Prop
{
public int P { get { return 1; } }
}
class Prop2: Prop
{
public Prop2() { p = base.P; }
protected int p;
public new int P { get { return p; } set { p = value; } }
}

class Test
{
public static void Main()
{
Prop2 p2 = new Prop2();
Prop p = p2;
System.Console.WriteLine("p2.P=={0}", p2.P);
p2.P = 5;
System.Console.WriteLine("p2.P=={0}", p2.P);
// p.P = 5; // <-- will error
}
}
--
Helge Jensen
mailto:he**********@slog.dk
sip:he**********@slog.dk
-=> Sebastian cover-music: http://ungdomshus.nu <=-
Nov 30 '05 #10


Helge Jensen wrote:

jm*****@gmail.com wrote:
I've used it to add accessors to a property, when a base class has a
property that's read-only, but I want it to be read-write in a derived
class. Unfortunately I have to create an intermediate class to do it:

How about:


Ups, sorry, read that wrong:

abstract class Prop
{
public abstract int P { get; }
}
class Prop2: Prop
{
public int p;
public override int P {get { return p; } }
}

class Test
{
public static void Main()
{
Prop2 p2 = new Prop2();
Prop p = p2;
System.Console.WriteLine("p2.P=={0}", p2.P);
System.Console.WriteLine("p.P=={0}", p.P);
p2.p = 5;
System.Console.WriteLine("p2.P=={0}", p2.P);
System.Console.WriteLine("p.P=={0}", p.P);
}
}
--
Helge Jensen
mailto:he**********@slog.dk
sip:he**********@slog.dk
-=> Sebastian cover-music: http://ungdomshus.nu <=-
Nov 30 '05 #11
Making that field public doesn't seem like a very good design. For
example, I want to make sure that Height is never negative, and I can't
guarantee that if the field is public.

The other alternative would be to use a set method instead of an
accessor:

abstract class B {
public abstract int Height { get; }
}

class D : B {
public override int Height { get { ... } }
public void SetHeight(int value) { ... }
}

But that's ugly.. properties are supposed to replace set and get
methods. This is C#, not Java. Making an intermediate class and
reintroducing the property with 'new' isn't beautiful either, but it
does what I want, and it'll work correctly if anyone wants to set the
property with reflection.

I don't know why I can't just add the accessor in the derived class,
honestly. It doesn't seem like it'd break anything.

Jesse

Nov 30 '05 #12
Marina was correct.

Of course it won't work *exactly* like a virtual method. Without
virtual, all you have is static binding, which means you'll call
Foo.f() when you're calling through a Foo reference and Bar.f() when
you're calling through a Bar reference.

But that may be good enough if you have control over all the code
that's using the class. That is, you can create a Bar object, and its
f() method will do what you want as long as you never assign it to a
Foo variable, never pass it to a method that expects a Foo, and none of
the inherited methods from Foo call f().

Jesse

Nov 30 '05 #13


jm*****@gmail.com wrote:
Marina was correct.
The statement was: "That also means you can't call the original version
without casting to the base class.". This statement is false.

Of course the only proper solution is to declare f() virtual in Foo.
But that may be good enough if you have control over all the code
that's using the class. That is, you can create a Bar object, and its
f() method will do what you want as long as you never assign it to a
Foo variable, never pass it to a method that expects a Foo, and none of
the inherited methods from Foo call f().


It's *very* hard to be sure you have control over all the code using the
class, for one thing, the type-system won't help you at all, neither
staticly or dynamicly. Since you inherit from Foo, and need to override
f() in Foo it's rather likely that some other code is going to use your
Bar instance as a Foo.

Using "new" to override a method that should have been virtual is a hack
that leads to unreadable code. If you do have complete control over the
code that uses Bar it can be replaced by, either naming the f() in Bar
something else -- proper to it's usage in Bar, or:

class Bar {
public void HACK_SINCE_f_IS_NOT_VIRTUAL() { /* impl. of f() */ }
public new f() {
throw new NotSupported(
string.format("call HACK_SINCE_f_IS_NOT_VIRTUAL instead"));
}

Which clearly shows that a hack is in progress.

--
Helge Jensen
mailto:he**********@slog.dk
sip:he**********@slog.dk
-=> Sebastian cover-music: http://ungdomshus.nu <=-
Nov 30 '05 #14


jm*****@gmail.com wrote:
Making that field public doesn't seem like a very good design. For
example, I want to make sure that Height is never negative, and I can't
guarantee that if the field is public.
There is always:

class Prop2: Prop
{
public int p { get { ...; } set { ...; } }
public override int P { get { return p; } }
}

:)
But that's ugly.. properties are supposed to replace set and get
methods. This is C#, not Java. Making an intermediate class and
reintroducing the property with 'new' isn't beautiful either, but it
does what I want, and it'll work correctly if anyone wants to set the
property with reflection.
Do you expect people to set it via reflection? if not, I wouldn't worry
about it. A a side note, the solution above also works via reflection.
I don't know why I can't just add the accessor in the derived class,
honestly. It doesn't seem like it'd break anything.


It would be perfectly sound from a typing-perspective, the problem is
that a property is treated as *one* function, not two - by the
typesystem. This is also why you cannot have get public and set
protected. I seem to vaguely recall some comments about this being
mended in C#2,... anyone?

You can actually use explicit interface implementation to side-step this
problem very nicely:

interface B {
int Height { get; }
}

class D : B {
int B.Height { get { return Height; } }
int Height { get { ...; } set { ...; } }
}
--
Helge Jensen
mailto:he**********@slog.dk
sip:he**********@slog.dk
-=> Sebastian cover-music: http://ungdomshus.nu <=-
Nov 30 '05 #15
It's false? If you have a base class A, and a derived class B. Class A has
a non-virtual method Foo, and B has its own version with new.

Now you have

B test = new B();

How do you call A's version of Foo without casting to an A first? If you
call 'test.Foo()', you will call B's version. Not A's.

Also, no one was saying that using 'new' is the right way to do it. The
original question is, why would you want to. The only answer I can think of
is that you don't want to do it unless you have no other option because you
have no control over the source code of the ancestor class.

"Helge Jensen" <he**********@slog.dk> wrote in message
news:uz**************@TK2MSFTNGP12.phx.gbl...


jm*****@gmail.com wrote:
Marina was correct.


The statement was: "That also means you can't call the original version
without casting to the base class.". This statement is false.

Of course the only proper solution is to declare f() virtual in Foo.
But that may be good enough if you have control over all the code
that's using the class. That is, you can create a Bar object, and its
f() method will do what you want as long as you never assign it to a
Foo variable, never pass it to a method that expects a Foo, and none of
the inherited methods from Foo call f().


It's *very* hard to be sure you have control over all the code using the
class, for one thing, the type-system won't help you at all, neither
staticly or dynamicly. Since you inherit from Foo, and need to override
f() in Foo it's rather likely that some other code is going to use your
Bar instance as a Foo.

Using "new" to override a method that should have been virtual is a hack
that leads to unreadable code. If you do have complete control over the
code that uses Bar it can be replaced by, either naming the f() in Bar
something else -- proper to it's usage in Bar, or:

class Bar {
public void HACK_SINCE_f_IS_NOT_VIRTUAL() { /* impl. of f() */ }
public new f() {
throw new NotSupported(
string.format("call HACK_SINCE_f_IS_NOT_VIRTUAL instead"));
}

Which clearly shows that a hack is in progress.

--
Helge Jensen
mailto:he**********@slog.dk
sip:he**********@slog.dk
-=> Sebastian cover-music: http://ungdomshus.nu <=-

Nov 30 '05 #16
> Did anyone EVER come across the need to use "new" in a method
declaration (breaking with inheritance / versioning)? Allthough I know
what it does and how it is used I really have a hard time to make up a
usefull real life scenario for it. Maybe you can give a practical
example from a real life?


Here's one that I need everytime I create a descendant of EventArgs.

public class SomethingHappenedEventArgs : EventArgs
{
new public static readonly SomethingHappenedEventArgs Empty = new SomethingHappenedEventArgs
();

public SomethingHappenedEventArgs()
{}

...
}

Reason being: Say you have a method that takes a MyEventArgs as a parameter
and you just want to pass an emtpy argument list. You can't pass EventArgs.Empty.

public void OnSomethingHappened(SomethingHappenedEventArgs args)
{
...
}

I suppose you could call it like OnSomethingHappened(new SomethingHappenedEventArgs())
or even OnSomethingHappened(null) though ;)

Providing the new Empty implementation just feels cleaner to me.
Nov 30 '05 #17
Sorry for the nonstandard quoting, Google Groups doesn't have a quote
button...

"It would be perfectly sound from a typing-perspective, the problem is
that a property is treated as *one* function, not two - by the
typesystem. This is also why you cannot have get public and set
protected. I seem to vaguely recall some comments about this being
mended in C#2,... anyone?"

I don't think this is accurate. A property is just a bit of metadata
that describes one or two functions, and as you mentioned, C# 2.0 lets
you specify different accessibility on the set and get accessors. You
could do the same with Managed C++ even in .NET 1.1, IIRC.

In fact, you can add a set accessor to an inherited read-only property
in C++/CLI and ILASM. (See the C++ code below, which compiles with
/clr:safe and passes peverify.) This is a limitation of C#, not .NET.

"You can actually use explicit interface implementation to side-step
this
problem very nicely"

Unfortunately that only works for interfaces, not base classes.

Jesse

===== C++ CODE =====

// propAccTestCPP.cpp : main project file.

#include "stdafx.h"

using namespace System;

ref class Base abstract
{
public:
property int Prop
{
virtual int get() abstract;
}
};

ref class Derived : public Base
{
private:
int x;

public:
property int Prop
{
virtual int get() override
{
return x;
}
virtual void set(int value)
{
x = value;
}
}
};

int main(array<System::String ^> ^args)
{
Derived^ d = gcnew Derived();
d->Prop = 123;
System::Console::WriteLine(d->Prop);
return 0;
}

Dec 1 '05 #18


Marina wrote:
B test = new B();

How do you call A's version of Foo without casting to an A first? If you
call 'test.Foo()', you will call B's version. Not A's.
A testa = test;
testa.Foo(); // invokes A.Foo on test

This can easily happen without the programmer noticing, for example if a
function returns the value, or assigns it to a member. The type-system
won't warn you -- the program will compile, run, and behave contrary to
the usual behaviour.
Also, no one was saying that using 'new' is the right way to do it. The
original question is, why would you want to. The only answer I can think of
is that you don't want to do it unless you have no other option because you
have no control over the source code of the ancestor class.


What I'm saying is, that even in this case, it's not too good, and you
would probably do better by using another name for the member.

new doesn't make the member virtual.

new overloads the semantics of a member after the static type of it's
object. This is the opposite of the normal semantics of members, which
are either sigularly defined, or overloaded after the dynamic-type of
it's object.

--
Helge Jensen
mailto:he**********@slog.dk
sip:he**********@slog.dk
-=> Sebastian cover-music: http://ungdomshus.nu <=-
Dec 1 '05 #19


jm*****@gmail.com wrote:
Sorry for the nonstandard quoting, Google Groups doesn't have a quote
button...
no problem.
"It would be perfectly sound from a typing-perspective, the problem is
that a property is treated as *one* function, not two - by the
typesystem. This is also why you cannot have get public and set
protected. I seem to vaguely recall some comments about this being
mended in C#2,... anyone?"

I don't think this is accurate. A property is just a bit of metadata
that describes one or two functions, and as you mentioned, C# 2.0 lets
you specify different accessibility on the set and get accessors. You
could do the same with Managed C++ even in .NET 1.1, IIRC.
I should have said: "by the C# typesystem", I didn't notice the
ambiguity -- possibly because I continued "...mended in C#2...".
In fact, you can add a set accessor to an inherited read-only property
in C++/CLI and ILASM. (See the C++ code below, which compiles with
/clr:safe and passes peverify.) This is a limitation of C#, not .NET.
I think we agree on that.
"You can actually use explicit interface implementation to side-step
this
problem very nicely"

Unfortunately that only works for interfaces, not base classes.


Another nail in the coffin of abstract classes, a small one though.
--
Helge Jensen
mailto:he**********@slog.dk
sip:he**********@slog.dk
-=> Sebastian cover-music: http://ungdomshus.nu <=-
Dec 1 '05 #20
You are casting test to A (at least statically) when you assign it to
an A variable.

Jesse

Dec 2 '05 #21


jm*****@gmail.com wrote:
You are casting test to A (at least statically) when you assign it to
an A variable.


I realize that "without a cast" is a bit ambiguous, I would usually
interpret it as without using the cast operator -- which is the issue here.

< splitting hairs >
Actually I can't find your definition of a cast in ISO/IEC
23270:2003(E). I can find a definition of "implicit conversions" which
captures the above:

* From any class-type S to any class-type T, provided S is derived from T.
* From any class-type S to any interface-type T, provided S implements T.
* From any interface-type S to any interface-type T, provided S is
derived from T.

Although there are a few examples which hints to (unqualified) "cast"
being used the way you specify.
</ splitting hairs >

Claiming that the need to implicitly convert (cast) from a type to
another will help the programmer in any way when using "new" is void.
Implicit conversion is exactly implicit.

In many cases it is not even clear from the immediate context whether an
implicit conversion occurs. Further more, changing a declaration, may
change a situation without implicit conversion to one without, or
vice-versa, and change the semantics of the program -- without so much
as a warning.

BTW: This is also why overloading with sub-classing is so error-prone.

--
Helge Jensen
mailto:he**********@slog.dk
sip:he**********@slog.dk
-=> Sebastian cover-music: http://ungdomshus.nu <=-
Dec 9 '05 #22

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

3 posts views Thread by Woodmon | last post: by
6 posts views Thread by jas_lx | last post: by
14 posts views Thread by JPRoot | last post: by
8 posts views Thread by Keith Smith | last post: by
5 posts views Thread by Stoyan | last post: by
3 posts views Thread by methodios | last post: by
5 posts views Thread by Marcel Hug | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.