Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pros and cons of 'new' properties in C# / .Net?

Considering the following sample code:

// delivery strategies
public abstract class DeliveryStrategy { ... }
public class ParcelDelivery : DeliveryStrategy { ... }
public class ShippingContainer : DeliveryStrategy { ... }

and the following sample Order class:

// order (base) class
public abstract class Order
{
    private DeliveryStrategy delivery;

    protected Order(DeliveryStrategy delivery)
    {
        this.delivery = delivery;
    }

    public DeliveryStrategy Delivery
    {
        get { return delivery; }
        protected set { delivery = value; }
    }
}

When i derive a new type of order class, it will inherit the Delivery property of type DeliveryStrategy.

Now, when it is given that CustomerOrders must be delivered using the ParcelDelivery strategy, we could consider 'new'ing the Delivery property in the CustomerOrder class:

public class CustomerOrder : Order
{
    public CustomerOrder()
        : base(new ParcelDelivery())
    { }

    // 'new' Delivery property
    public new ParcelDelivery Delivery
    {
        get { return base.Delivery as ParcelDelivery; }
        set { base.Delivery = value; }
    }
}

(The CustomerOrder obviously needs to ensure that is compatible (polymorph) with Order)

This allows direct usage of the ParcelDelivery strategy on CustomerOrder without the need for casting.

Would you consider using this pattern? why / why not?

Update: i came up with this pattern, instead of using generics, because i want to use this for multiple properties. I don't want to use generic type arguments for all these properties

like image 641
oɔɯǝɹ Avatar asked Jun 03 '09 11:06

oɔɯǝɹ


People also ask

What are the benefits of using properties?

The main advantage of properties is that they allow us to encapsulate our data inside our class in such a way that we can control access to our class's data through only the properties and not by allowing outside programs to access our fields directly.

Why should I use properties in C#?

Properties enable a class to expose a public way of getting and setting values, while hiding implementation or verification code. A get property accessor is used to return the property value, and a set property accessor is used to assign a new value.

What is the difference between properties and methods in C#?

Using a method causes something to happen to an object, while using a property returns information about the object or causes a quality about the object to change.

What is AC property?

A C# property have two accessors, get property accessor and set property accessor. A get accessor returns a property value, and a set accessor assigns a new value. The value keyword represents the value of a property. Properties in C# and . NET have various access levels that is defined by an access modifier.


2 Answers

I'd prefer to make the type generic:

public abstract class Order<TDelivery> where TDelivery : Delivery
{
    public TDelivery Delivery { ... }
    ...
}

public class CustomerOrder : Order<ParcelDelivery>
{
    ...
}

This ensures type safety at compile-time, rather than leaving it up to execution time. It also prevents the situation of:

CustomerOrder customerOrder = new CustomerOrder();
Order order = customerOrder;
order.Delivery = new NonParcelDelivery(); // Succeeds!

ParcelDelivery delivery = customerOrder.Delivery; // Returns null

Ouch.

I regard new as usually a last resort. It introduces added complexity both in terms of implementation and use.

If you don't want to go down the generic route, I'd introduce a genuinely new property (with a different name).

like image 193
Jon Skeet Avatar answered Nov 13 '22 11:11

Jon Skeet


I think this is a good pattern. It makes it easier to explicitly use derived types by removing the need to cast the result, and it doesn't 'break' the base class behavior. Actually, a similar pattern is used in some classes in the BCL, for instance look at the DbConnection class hierarchy :

  • DbConnection.CreateCommand() returns a DbCommand
  • SqlConnection.CreateCommand() hides the base implementation using 'new' to return a SqlCommand.
  • (other DbConnection implementations do the same)

So, if you manipulate the connection object through a DbConnection variable, CreateCommand will return a DbCommand ; if you manipulate it through a SqlConnection variable, CreateCommand will return a SqlCommand, avoiding the cast if you're assigning it to a SqlCommand variable.

like image 40
Thomas Levesque Avatar answered Nov 13 '22 11:11

Thomas Levesque