Why use the new modifier?

  • Thread starter Thread starter Peter Aitken
  • Start date Start date
P

Peter Aitken

Supposedly you are supposed to use new when you want a member in a derived
class to hide a member of the same name in the base class:

class A
{
public int total;
}

class B:A
{
public new float total;
}

But omitting it causes only a warning, no error, and the class seems to work
the same either way. Does it have any real purpose?

Thanks,
 
If you find yourself thinking I need to use the new modifier in the code you're writing a big red flashing light on the wall should start flashing with the text

WARNING! WARNING! DESIGN FLAW! DESIGN FLAW!

The new modifier is for handling the situation where your base class (which you are not in control of) introduces a member whose name collides with a member your derived class already has. In this situation the compiler warns you that you have a theoretical ambiguity (although what happens is well defined). It is asking you to specify for this collision whether you are intending to override or whether your method is completely separate from the base class version (the latter is what happens at runtime if you do nothing).

The C# compiler is asking you to be *explicit* about your intentions which a common theme in C#. Its only a warning so it doesn't break existing code.

If you get this in code you are writing when you compile it either override (if that is what you actually meant) or rename your method so it doesn't collide.

Regards

Richard Blewett - DevelopMentor
http://www.dotnetconsult.co.uk/weblog
http://www.dotnetconsult.co.uk

Supposedly you are supposed to use new when you want a member in a derived
class to hide a member of the same name in the base class:

class A
{
public int total;
}

class B:A
{
public new float total;
}

But omitting it causes only a warning, no error, and the class seems to work
the same either way. Does it have any real purpose?
 
Sure it has a purpose. It silences the warning.

Your goal here is not merely to create programs that work, but one that
work _AND_ can be modified (by someone else) to work, later when the
requirements change.

When some maintance programmer tries recompiling your code, and sees the
warning, he'll probably say, "Silly programmer; he doesn't need total in B,
because there's already one in A." and remove it --- and the program will
fail. By adding the "new" you are explicitly saying to all who may see this
code later, "Yes, dammit, I want a "total" in B that's separate & distinct
from the total in A".

--
--
Truth,
James Curran
[erstwhile VC++ MVP]

Home: www.noveltheory.com Work: www.njtheater.com
Blog: www.honestillusion.com Day Job: www.partsearch.com
 
WARNING! WARNING! DESIGN FLAW! DESIGN FLAW!

Oh dear, I guess I've been doing it all wrong for years now.

Or maybe not.

Here's my design, and my use of 'New'. Could you provide another option?

Abstract Class Order
{
OrderStatus Status; //among other things
}
OrderStatus is an enum (custom class - not raw enum) with New,Open,Closed.
basically, an Order knows if its new,open,closed and how to manage business
rules given these statuses. ALL Orders will have these statuses, and
probably more.

From Order come SalesOrder,PurchaseOrder,WorkOrder,DeliveryOrder etc etc.

So I have
public class WorkOrder:Order
{
new WorkOrderStatus Status; //different [smarter] Status object
}
and
public class WorkOrderStatus:OrderStatus
{
//more statuses, new methods, overrides etc
}

Is that a design flaw? I've been using this model extensively for years,
and am extremely glad that c# provides the 'new' keyword.


Richard Blewett said:
If you find yourself thinking I need to use the new modifier in the code
you're writing a big red flashing light on the wall should start flashing
with the text
WARNING! WARNING! DESIGN FLAW! DESIGN FLAW!

The new modifier is for handling the situation where your base class
(which you are not in control of) introduces a member whose name collides
with a member your derived class already has. In this situation the compiler
warns you that you have a theoretical ambiguity (although what happens is
well defined). It is asking you to specify for this collision whether you
are intending to override or whether your method is completely separate from
the base class version (the latter is what happens at runtime if you do
nothing).
The C# compiler is asking you to be *explicit* about your intentions
which a common theme in C#. Its only a warning so it doesn't break existing
code.
If you get this in code you are writing when you compile it either
override (if that is what you actually meant) or rename your method so it
doesn't collide.
 
How do you use these classes? Making the Status's public, if you write

using System;
class App
{
static void Main(string[] args)
{
WorkOrder w = new WorkOrder();
w.Status = new OrderStatus();
Order o = w;
Console.WriteLine(o.Status == null);
}
}

this prints out True as the Status's are unrelated. So do you use the order classes polymorphically - maybe with virtual methods that access the derived class's Status?

Regards

Richard Blewett - DevelopMentor
http://www.dotnetconsult.co.uk/weblog
http://www.dotnetconsult.co.uk

Oh dear, I guess I've been doing it all wrong for years now.

Or maybe not.

Here's my design, and my use of 'New'. Could you provide another option?

Abstract Class Order
{
OrderStatus Status; //among other things
}
OrderStatus is an enum (custom class - not raw enum) with New,Open,Closed.
basically, an Order knows if its new,open,closed and how to manage business
rules given these statuses. ALL Orders will have these statuses, and
probably more.

From Order come SalesOrder,PurchaseOrder,WorkOrder,DeliveryOrder etc etc.

So I have
public class WorkOrder:Order
{
new WorkOrderStatus Status; //different [smarter] Status object
}
and
public class WorkOrderStatus:OrderStatus
{
//more statuses, new methods, overrides etc
}

Is that a design flaw? I've been using this model extensively for years,
and am extremely glad that c# provides the 'new' keyword.
 
WARNING! WARNING! DESIGN FLAW! DESIGN FLAW!

Oh dear, I guess I've been doing it all wrong for years now.

Or maybe not.

Here's my design, and my use of 'New'. Could you provide another option?

Abstract Class Order
{
OrderStatus Status; //among other things
}
OrderStatus is an enum (custom class - not raw enum) with New,Open,Closed.
basically, an Order knows if its new,open,closed and how to manage business
rules given these statuses. ALL Orders will have these statuses, and
probably more.

From Order come SalesOrder,PurchaseOrder,WorkOrder,DeliveryOrder etc etc.

So I have
public class WorkOrder:Order
{
new WorkOrderStatus Status; //different [smarter] Status object
}
and
public class WorkOrderStatus:OrderStatus
{
//more statuses, new methods, overrides etc
}

Is that a design flaw? I've been using this model extensively for years,
and am extremely glad that c# provides the 'new' keyword.


Richard Blewett said:
If you find yourself thinking I need to use the new modifier in the code
you're writing a big red flashing light on the wall should start flashing
with the text
WARNING! WARNING! DESIGN FLAW! DESIGN FLAW!

The new modifier is for handling the situation where your base class
(which you are not in control of) introduces a member whose name collides
with a member your derived class already has. In this situation the compiler
warns you that you have a theoretical ambiguity (although what happens is
well defined). It is asking you to specify for this collision whether you
are intending to override or whether your method is completely separate from
the base class version (the latter is what happens at runtime if you do
nothing).
The C# compiler is asking you to be *explicit* about your intentions
which a common theme in C#. Its only a warning so it doesn't break existing
code.
If you get this in code you are writing when you compile it either
override (if that is what you actually meant) or rename your method so it
doesn't collide.
 
Richard,

I have a mature framework where much is held in metadata, which initialises
these as required. All classes actually have a constructor with 2
parameters: a parent container and an xml element metadata descriptor. So
the objects do get constructed and used appropriately.

You can read about it here:
http://members.optushome.com.au/rcerny/GenieWhitePaper.pdf

Sorry if I seemed a bit terse earlier, but you were SHOUTING, and this is
one of those design concepts that I am particularly proud of.

Radek

Richard Blewett said:
How do you use these classes? Making the Status's public, if you write

using System;
class App
{
static void Main(string[] args)
{
WorkOrder w = new WorkOrder();
w.Status = new OrderStatus();
Order o = w;
Console.WriteLine(o.Status == null);
}
}

this prints out True as the Status's are unrelated. So do you use the
order classes polymorphically - maybe with virtual methods that access the
derived class's Status?
Regards

Richard Blewett - DevelopMentor
http://www.dotnetconsult.co.uk/weblog
http://www.dotnetconsult.co.uk

Oh dear, I guess I've been doing it all wrong for years now.

Or maybe not.

Here's my design, and my use of 'New'. Could you provide another option?

Abstract Class Order
{
OrderStatus Status; //among other things
}
OrderStatus is an enum (custom class - not raw enum) with New,Open,Closed.
basically, an Order knows if its new,open,closed and how to manage business
rules given these statuses. ALL Orders will have these statuses, and
probably more.

From Order come SalesOrder,PurchaseOrder,WorkOrder,DeliveryOrder etc etc.

So I have
public class WorkOrder:Order
{
new WorkOrderStatus Status; //different [smarter] Status object
}
and
public class WorkOrderStatus:OrderStatus
{
//more statuses, new methods, overrides etc
}

Is that a design flaw? I've been using this model extensively for years,
and am extremely glad that c# provides the 'new' keyword.
 
What I'm trying to understand is why the Order class has a Status. I can see a number of options to model this but this would seem to me to be the most useful (although obviously I can't see your exact usage model). You obviously never create an Order directly because it's abstract so it the WorkOrder's Status simply to provide a strongly typed accessor to the status (so its a WorkOrderStatus not an OrderStatus) so to reduce casting?

abstract class Order
{
protected OrderStatus status;
}
abstract class OrderStatus
{
}

class WorkOrder : Order
{
public WorkOrder()
{
status = new WorkOrderStatus();
}
public WorkOrderStatus Status
{
get{ return (WorkOrderStatus)status;
}
}
class WorkOrderStatus : OrderStatus
{
}

So what is it about the above that doesn't work - which of your requirements isn't fulfilled?

Regards

Richard Blewett - DevelopMentor
http://www.dotnetconsult.co.uk/weblog
http://www.dotnetconsult.co.uk

Richard,

I have a mature framework where much is held in metadata, which initialises
these as required. All classes actually have a constructor with 2
parameters: a parent container and an xml element metadata descriptor. So
the objects do get constructed and used appropriately.

You can read about it here:
http://members.optushome.com.au/rcerny/GenieWhitePaper.pdf

Sorry if I seemed a bit terse earlier, but you were SHOUTING, and this is
one of those design concepts that I am particularly proud of.

Radek
 
Richard,

my methodology basically places all the 'features' of a business object into
that object as first-class public members, so an order has a whole lot of
methods and a whole lot of fields (such as Status). A WorkOrder adds more
methods and fields, and of overrides some virtual methods. A
WorkOrderStatus does the same; a WorkOrder asks its Status object to perform
methods that are not even declared in a simple OrderStatus. Also, all
members are created through reflection by the runtime, as denoted in the xml
metadata, so casting as you have written (as well as the 'status = new
WorkOrderStatus();' will not work.

Radek

Richard Blewett said:
What I'm trying to understand is why the Order class has a Status. I can
see a number of options to model this but this would seem to me to be the
most useful (although obviously I can't see your exact usage model). You
obviously never create an Order directly because it's abstract so it the
WorkOrder's Status simply to provide a strongly typed accessor to the status
(so its a WorkOrderStatus not an OrderStatus) so to reduce casting?
 
I still don't understand why Order has a Status unless some ***Order classes don't provide their own specialized version of the status

Regards

Richard Blewett - DevelopMentor
http://www.dotnetconsult.co.uk/weblog
http://www.dotnetconsult.co.uk

Richard,

my methodology basically places all the 'features' of a business object into
that object as first-class public members, so an order has a whole lot of
methods and a whole lot of fields (such as Status). A WorkOrder adds more
methods and fields, and of overrides some virtual methods. A
WorkOrderStatus does the same; a WorkOrder asks its Status object to perform
methods that are not even declared in a simple OrderStatus. Also, all
members are created through reflection by the runtime, as denoted in the xml
metadata, so casting as you have written (as well as the 'status = new
WorkOrderStatus();' will not work.

Radek
 
Richard,

in Order, is code like:
if (Status.isCancelled()).....
OrderStatus returns false - there is no cancelled status.
WorkOrderStatus does have a cancelled status and returns appropriately. One
of our clients, who uses a subclass of WorkOrder,lets say AcmeWorkOrder, has
of course an AcmeWorkOrderStatus class that adds a few statuses. This
particular client has 2 statuses that are effectively cancelled, but they
needed to differentiate from Client cancelled and Supplier Cancelled. So
the code way back in Order, if its actually an AcmeWorkOrder, will ask its
Status if its cancelled. But at runtime, it will be talking to an
AcmeWorkOrderStatus object, and behave correctly (cancelled orders may get
the option to reinstate etc).

All of the above is stored in metadata xml documents, and c# code is only
needed where lower-level business rules are required. The runtime manages
all of the construction; it only constructs the most recent Status, and
equates all prior instances to it, so the Status inside points to the same
instance as the "new" Status in subclasses.

Maybe this was a poor example to begin with. WorkOrders have a collection
of WorkOrderItems. When you subclass WorkOrder to AcmeWorkOrder, you get
with it a collection of WorkOrderItems. But you want a collection of
AcmeWorkOrderItems, so you use the "new" operator. The WorkOrder class is
not abstract, but quite thin from a data point of view. It does embody all
of our design patterns, and so has a lot of code and virtual methods, but
only a few persisted fields. When we engage a client requiring Work Order
Processing, we simply subclass WorkOrder and WorkOrderItem, whack in a few
more fields the client requires and presto! A fully-tailored highly
functional Order Processing system in a matter of hours (the framework has a
built in O/R mapper with full schema syncronisation).

This would not be possible without the "new" keyword.

Richard Blewett said:
I still don't understand why Order has a Status unless some ***Order
classes don't provide their own specialized version of the status
 
Back
Top