tags:

views:

131

answers:

5

I have SalesMan class which is inherited from User class and also implements ISalesMan interface.

public class SalesMan : User, ISalesMan { ... }

I need to convert user objects into salesman objects. I understand that direct casting from User type of objects into SalesMan type is not possible. How should I do the converting? I'm thinking two different ways:

  1. Creating constructor for SalesMan class that takes User parameter and initializes new SalesMan object based on the given User.

  2. Creating new method for the SalesMan class that takes User as a parameter and returns new SalesMan object based on the given User parameter.

...or is there even more smarter way to solve this kind of a problem?

A: 

Option 1 is the tidiest and most intuitive.

sipwiz
+4  A: 

The constructor described in Option 1 is what I would expect to find if I were poking around an unfamiliar API.

They can be boring beasts to write though, and you may forget to update them when adding new fields to the User class. So (if performance considerations allow), consider writing an "intelligent" constructor using reflection, along the lines of this example.

On the issue of constructors versus factory methods, the Framework Design Guidelines offers the following advice:

  • DO prefer constructors to factories, because they are generally more usable, consistent, and convenient then specialized construction mechanisms.

  • CONSIDER using a factory if you need more control than can be provided by constructors over the creation of the instances.

  • DO use a factory where a developer might not know which type to
    construct, such as when coding
    against a base type or interface.

  • CONSIDER using a factory if having a named method is the only way to make the operation self-explanatory.

Ian Nelson
The "intelligent" copy constructor described in the article only works for value type fields. Additionally, if many instances must be constructed like this Reflection may be too slow.
Brian Rasmussen
I wouldn't call option 1 a copy constructor. They are usually of the form: MyClass(MyClass o)This would be called a conversion constructor in C++
Seb Rose
@Seb Rose you're right - edited.
Ian Nelson
A: 

If you really want to create a SalesMan object from a User object then either of the options you describe would work.

But I think you need to ask yourself what you are trying to do. When/why does a User become a SalesMan? Are you trying to change the bahaviour of an existing object? Do behaviours change regularly in your system?

Depending on your needs, you might consider using the Strategy or Template Method patterns.

Seb Rose
A: 

I use option 1. upgrade constructor or conversion constructor.

Kunal S
A: 

The answers you've already received are more than sufficient. However, I noticed you mentioned that casting wasn't possible. If you have some sort of reason to employ casts, you can make it possible by overloading an operator.

public static explicit operator SalesMan(User user)
{
    // Your logic to create a new SalesMan using data from user.
}

Determining which solution is smarter would require more information than was provided in your original post. However, I tend to air on the sides of completeness and versatility, and would considering doing both.

public class SalesMan
{
    public SalesMan(User user)
    {
        // Your logic to create a new SalesMan using data from user.
    }

    public static explicit operator SalesMan(User user)
    {
        return new SalesMan(user);
    }
}

And Ian's right. General rule of thumb is use a factory only when you have a functional requirement that can't be met with a constructor, or the constraints of the language start to get in your way. For example, needing two different constructors with an identical signature.

Daniel Henry