Click here to Skip to main content
15,887,485 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Not really sure how to explain it in a one-liner but here's my situation.

I have an abstract base class called "Deal" which has a property in it which is of a class "Inventory"

Now a deal can be either Cash, Finance, Lease, Wholesale or Rent-To-Own which is why it's of type Deal. It's also abstract as each of the deal types have some properties that don't apply to other but they all have a set of shared so the various deal types (i.e. - Finance, Lease, etc.) inherit from the base class Deal and have their own added methods and properties.

The same is true with another abstract class of "Inventory". Inventory can be things like car, truck, boat, RV, etc.) so therefore I have a class of Inventory.

Here's the issue:

A deal must contain a unit in inventory. For example, you finance a car or you lease an RV then you have a Deal with an inventory property of type Inventory or whatever the case may be.

When I create the Deal class and I add a property to it like SoldUnit as type Inventory, the T is inherited from the Deal class. How can I create a generic property of type Inventory inside of the Deal class?

Deal won't really work because of the number of possibilities, so how could I make a generic "SoldUnit" property which references an Inventory class inside of the Deal class? And while maintaining strict typing? I know I could make a property called SoldUnit with a type of object or dynamic, but is there a better way?

Here is an excerpt of the code: It doesn't work because type T is already a DealType, but it's the two properties [ ret.Vehicle = new Car(); and ret.SoldUnit = new Car(); ] that I'm trying to populate with a specific inventory type (car, truck, rv, boat, etc.) in the Get() method. The specific inventory type is determined by a flag in the database field.

public abstract class Deal<T>
{
    public string Uid { get; set; } = Guid.NewGuid().ToString();
    public DealTypes DealType { get; set; } = DealTypes.Finance;

    public Buyer Customer { get; set; }
    public Inventory<T> Vehicle { get; set; }
    public Location Location { get; set; }
    public Inventory<T> SoldUnit { get; set; }

    public abstract T Add(string id);
    public abstract T Update(string id);
    public abstract T Get(string id);
}

public abstract class Inventory<T>
{
    public string Uid { get; internal set; } = Guid.NewGuid().ToString();
    public Location Location { get; set; }
    public string StockNumber { get; set; } = "";
}

public class Cash : Deal<Cash>
{
    public decimal TradeAllowance { get; set; }
    public decimal TradePayoff { get; set; }
    public decimal TotalDown { get; set; }
    public decimal DueOnDelivery { get; set; }

    public override Cash Get(string id)
    {
        var ret = new Cash();
        ret.Customer = new Buyer();
        ret.Vehicle = new Car();
        ret.Location = new Location();
        ret.SoldUnit = new Car();
   }
}

public class Car : Inventory<Car>
{
    public decimal GrossWeight { get; set; }
    public decimal NetWeight { get; set; }
    public string Branded { get; set; } = "";
    public string FuelType { get; set; } = "";
    public string Trim { get; set; } = "";
    public string Body { get; set; } = "";
    public int Cylinders { get; set; }
    public decimal EngineSize { get; set; }
    public string TransmissionType { get; set; } = "";
    public string Suspension { get; set; } = "";
    public string InteriorColor { get; set; } = "";

    public bool OdometerExceedsLimit { get; set; }
    public bool OdometerTrueMileageUnknown { get; set; }
    public bool OdometerFiveDigit { get; set; }


    public string TitleNumber { get; set; } = "";
    public DateTime? TitleDate { get; set; }
    public string TitleState { get; set; } = "";
    public DateTime? TitleDue { get; set; }
    public DateTime? TitleReceived { get; set; }
}


Is there a way to do this?

Thanks!

What I have tried:

I've tried making the Deal class with two types
public class Deal<TDeal, TInventory>
but then I would have to make a class for every possible combination of deal / inventory type. So far, the only thing I can think of that would work is to make the Vehicle and SoldUnit properties of type object or dynamic but then I don't get the strong typing or the intellisense.

public dynamic Vehicle { get; set; }

public object SoldUnit{ get; set; }
Posted
Updated 27-Sep-17 2:03am
Comments
Nick4978 27-Sep-17 7:44am    
In a nutshell, this is the part I'm trying to make work:

    
    public abstract class Deal<T>
    {
        public Inventory<AnyVehicleType> Vehicle { get; set; }
        public Inventory<AnyVehicleType> SoldUnit { get; set; }
    }


AnyVehicleType is just psuedo-code here but would be a property of type Inventory (car, truck, boat, etc.) inside of the Deal class which could be things like finance, lease, wholesale, etc.
Richard Deeming 27-Sep-17 12:04pm    
Why do you need the generic type parameter on the Inventory class? It doesn't seem to be used anywhere.

If there is a reason to have it, could you create a non-generic base class?
public abstract class Inventory
{
    public string Uid { get; internal set; } = Guid.NewGuid().ToString();
    public Location Location { get; set; }
    public string StockNumber { get; set; } = "";
}

public abstract class Inventory<T> : Inventory
{
}

1 solution

But both Deal and Inventory are abstract classes so you cannot create either of them. You could make Deal a real class and use an enumeration to decide which type it is; same with Inventory. And you cannot do something like
public class Car : Inventory<Car>

You cannot create a type that has not yet been defined.

I think you are over engineering your classes.
 
Share this answer
 
Comments
Nick4978 27-Sep-17 8:22am    
But neither Deal nor Inventory should ever be created on their own because by themselves, they are nothing. They only have some base properties that are used in the real classes. For example, all Inventory objects have a Uid and some sort of serial number and all Deals have a sold unit and a customer. Even if I removed abstract, I still have the same problem with any deal type having a property of any inventory. It would be too messy to make something like:

public class Deal<T>
{
    public Car SoldCar {get; set; }
    public Truck SoldTruck {get; set; }
    public RV SoldRV {get; set; }
    public Boat SoldBoat {get; set; }
}

etc..
Richard MacCutchan 27-Sep-17 9:00am    
I don't think you fully understand abstract classes, inheritance or generics. Your whole approach appears to be based on misunderstandings. Creating an abstract class for Deal is fine, but each class that inherits it is a new class, and cannot be used in the way you are doing. You need something like:

abstract class Deal
{
// properties and methods common to all subclasses
};
class Car : Deal // for example
{
int engineCapacity; // a field unique to a Car
};
Nick4978 27-Sep-17 12:34pm    
Maybe I'm misunderstanding then. But in your example, you have class Car which inherits from Deal. Those two are completely different. A "Car" is a unit of "Inventory" whereas a "Deal" is a base class of a Finance, Lease, Cash, Wholesale, etc. type of transaction (deal) where the unit of inventory is only a property of it.

For example, I lease a car to John. The car is a 2014 Ford Mustang which I lease to John for $15,000.

Now I have a "lease" deal which has an lease amount (sales tax, fees, etc.) as part of the Deal, but the deal also contains a customer (which has name, address, phone, etc.) and the deal also has the car that I leased him (which has a year, make model, color, etc.)

So a Car would never inherit anything from Deal. The Deal would have to have a reference to the car that was sold. (As well as the customer it was sold to.)

The problem I have is that it might be a car, or it might be a truck, an RV, a boat, etc. And the deal itself might be a cash deal, lease deal, finance, wholesale, etc.

Am I making sense with this example? Or am I still misunderstanding what exactly you're saying?

Thanks!
Richard MacCutchan 27-Sep-17 13:21pm    
Sorry, that should have been one of the financial classes, e.g. Cash. But the comments are still valid.
Nick4978 27-Sep-17 20:42pm    
Okay. So that being the case then, if I didn't make the abstract class Deal with the <T> type, then I would have to get rid of the abstract methods that returned the specific Deal subclass and move them to the subclass?

i.e. -
public abstract class Deal {       
    ...properties...         
    public abstract T Add();            
    public abstract T Add(string id);            
    public abstract T Update();            
    public abstract T Update(string id);            
    public abstract T Get(string id);            
    public abstract List<T> Find();            
    public abstract bool Delete();            
    public abstract bool Delete(string id);
}

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900