Leander
Leander

Reputation: 568

Avoid multiple classes with only few different properties

I have two classes which are close to the same, except for one variable type.
The following example should demonstrate the problem.

class Customer
{
    byte Reputation;
    const byte MaximumReputation = 255;
    int Data;
    string MoreData;
    Briefcase EvenMoreData;

    public Customer(byte reputation, int data, string moreData, Briefcase evenMoreData)
    {
        Reputation = reputation;
        Data = data;
        MoreData = moreData;
        EvenMoreData = evenMoreData;
    }

    public float Level()
    {
        return Reputation / MaximumReputation;
    }

    public string Information()
    {
        return Data.ToString() + ", " + MoreData + EvenMoreData.Id;
    }
}
class CustomerDeluxe
{
    ushort Reputation;
    const byte MaximumReputation = 255;
    int Data;
    string MoreData;
    Briefcase EvenMoreData;

    public CustomerDeluxe(ushort reputation, int data, string moreData, Briefcase evenMoreData)
    {
        Reputation = reputation;
        Data = data;
        MoreData = moreData;
        EvenMoreData = evenMoreData;
    }

    public float Level()
    {
        return Reputation / MaximumReputation;
    }

    public string Information()
    {
        return Data.ToString() + ", " + MoreData + EvenMoreData.Id;
    }
}

Since Customers reputation won't exceed 255, I can store in a byte. In my application this field is a large array. That's why I would like to choose the smallest type possible. But there has to be another class for the few cases where the field can exceed a byte.

How can I "merge" these two classes?

Upvotes: 0

Views: 51

Answers (2)

CodingYoshi
CodingYoshi

Reputation: 27009

Use generics:

public class BaseCustomer<TRep>
{
    protected TRep Reputation;
}

public class CustomerDeluxe : BaseCustomer<ushort>
{
}

public class Customer : BaseCustomer<byte>
{
}

With generics, you are basically saying: "I am not sure what the type of TRep is but it will be manifested." A generic is said to be open when it is like above in BaseCustomer<TRep>. We will need to close it before we can use it. When we inherited it, then wevcloseed it with a specific type: in one instance we specified it to be ushort, in another we specified it to be byte.

And with some refactoring you can push most of the code to the BaseCustomer<T>:

public abstract class BaseCustomer<TRep>
{
    protected TRep Reputation;
    protected const byte MaximumReputation = 255;
    int Data;
    string MoreData;
    Briefcase EvenMoreData;

    public BaseCustomer(TRep reputation, int data, string moreData, Briefcase evenMoreData)
    {
        Reputation = reputation;
        Data = data;
        MoreData = moreData;
        EvenMoreData = evenMoreData;
    }

    public abstract float Level();


    public string Information()
    {
        return Data.ToString() + ", " + MoreData + EvenMoreData.Id;
    }
}

public class CustomerDeluxe : BaseCustomer<ushort>
{
    public CustomerDeluxe(ushort reputation, int data, string moreData, Briefcase evenMoreData) 
        : base(reputation, data, moreData, evenMoreData)
    {
    }

    public override float Level()
    {
        return Reputation / MaximumReputation;
    }
}

public class Customer : BaseCustomer<byte>
{
    public Customer(byte reputation, int data, string moreData, Briefcase evenMoreData) 
        : base(reputation, data, moreData, evenMoreData)
    {
    }

    public override float Level()
    {
        return Reputation / MaximumReputation;
    }
}

Upvotes: 2

elirandav
elirandav

Reputation: 2063

class CustomerDeluxe : CustomerBase
{
    ushort Reputation;

    public override ushort GetReputation()
    {
        return Reputation;
    }
}

class Customer : CustomerBase
{
    byte Reputation;
    public override ushort GetReputation()
    {
        return Reputation;
    }
}

abstract class CustomerBase
{
    const byte MaximumReputation = 255;
    public abstract ushort GetReputation();

    public float Level()
    {
        return GetReputation()/MaximumReputation;
    }
}

Upvotes: 1

Related Questions