0

Lets say that I have two classes and I want to create one method that will process data from two classes, how can I setup a method that will accept both where I can create them into objects of their type?

Public classs Car:Wheel
{

  public Color color {get; set;}
}

Public class Bike:Wheel

{
public bool hasRadio {get ; set;} 
public Color color {get; set;} 
}

Public class Wheel
{
  public WheelRimType {get; set;}
  public int WheelSize {get; set;} 
}

I want to pass either the class of car or bike to a method dynamically . When in that method how can transform it to the correct object so that I don't have to write the same method twice for each object?

Car c = new Car();
Bike b = new Bike();

ValidateVehichle(c);

private void ValidateVehicle(Type T??)
{
//convert to either car or bike here
} 
CodeMan03
  • 570
  • 3
  • 18
  • 43

5 Answers5

4
  1. Your car and bike "have" wheels, but are not "wheels", so you may want to read more about the has-a-is-a terminology when thinking about inheritance: has-a-is-a-terminology-in-object-oriented-language

  2. I believe you'd be better served creating a base class for Car and Bike and placing a Validation method in this base class which can then be implemented in Car and Bike. Something like the following:

  3. The base class VehicleBase would contain the common properties, color and Wheels properties following the "has-a" logic, in the example a VehicleBase would contain an IEnumerable<T> where T is Wheel, in which the vehicle could have zero or more wheels.


public abstract class VehicleBase
{
   public abstract bool Validate();
   public Color color { get; set;}
   public IEnumerable<Wheel> Wheels {get; set;}
}

public class Car : VehicleBase
{
   public override bool Validate()
   {
      //do Car validation
   }
}

public class Bike : VehicleBase
{
    public bool hasRadio {get ; set;} 
    public override bool Validate()
    {
      //do Bike validation
    }
}

public class Wheel
{
    public WheelRimType { get; set;}
    public int WheelSize {get; set;} 
}
Ryan Wilson
  • 10,223
  • 2
  • 21
  • 40
1

two classic possibilites

class Vehicle{

}

class Car : Vehicle{
}

class Bike : Vehicle{

}

then you can do

private void ValidateVehicle(Vehicle v)
{
//convert to either car or bike here
} 

The idiomatic way to do validatin would in fact to have the following

abstract class Vehicle{
      virtual bool Validate();
}

class Car : Vehicle{
     override bool Validate(){
     }
}

class Bike : Vehicle{
     override bool Validate(){
     }

}

the you would simply do vobj.Validate()

where vobj is an instance of a vehicle

also doable with interface

interface IVehicle{

}

class Car : IVehicle{
}

class Bike : IVehicle{

}

and

private void ValidateVehicle(Vehicle v)
{
//convert to either car or bike here
} 
pm100
  • 48,078
  • 23
  • 82
  • 145
0

use Generics:

ValidateVehichle<Car>(car);

private void ValidateVehicle<T>(T vehicle)
{
    // no convertion needed. use T as the type of the object
    T vehicle2 = vehicle;
    .....
} 

more on generics: https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/types/generics

Alex
  • 836
  • 9
  • 19
  • Using a generic method here provides no value over simply declaring the parameter as the base class (`Wheel` in the OP's example). – Kirk Woll May 23 '22 at 21:17
  • Kirk Woll, nvm, I see what you mean, and I can't argue with that, the purpose though was to show generics in general as a way of handling the passing of a type to a method – Alex May 23 '22 at 21:27
0

You can use generics and do something like this:

void Main()
{
    Car car = new Car();
    car.color = Color.Black;
    car.WheelSize = 22;
    
    ValidateVehicle<Car>(car)
}

private void ValidateVehicle<T>(T vehicle)
{
    // You still need to determine what time this object is
    T someVehicle = vehicle;
    Console.WriteLine("This is a generic method");
}

You could alternatively use overload methods too. You can have one name of a method with infinite overloads like this:

void Main()
{
    Car car = new Car();
    car.color = Color.Black;
    car.WheelSize = 22;
    
    Bike bike = new Bike();
    bike.color = Color.Red;
    bike.hasRadio = false;
    bike.WheelSize = 12;
    
    ValidateVehicle(car);
    ValidateVehicle(bike);
    
}

// You can define other methods, fields, classes and namespaces here
public class Car: Wheel
{
  public Color color { get; set; }
}

public class Bike : Wheel
{
    public bool hasRadio { get; set; }
    public Color color { get; set; }
}

public class Wheel
{
    public int WheelSize { get; set; } 
}

private void ValidateVehicle(Car car)
{
    Console.WriteLine("This is your car method");
}

private void ValidateVehicle(Bike bike)
{
    Console.WriteLine("This is your bike method");
}

output is:

This is your car method
This is your bike method
mathis1337
  • 1,426
  • 8
  • 13
  • Using the first response is in line with what I am thinking, however how do I determine what type of object has been passed in? If I can get the object then it will solve my problem> The second response would create redundant code especially if the validation is doing the same thing – CodeMan03 May 24 '22 at 15:46
0

The typical solution would be introduce a common interface, so that ValidateVehicle can work with either type:

public interface IVehicle{
    Color color {get; set;}
}

public class Car:Wheel, IVehicle {
    public Color color {get; set;}
}
public class Bike:Wheel, IVehicle
{
   public bool hasRadio {get ; set;} 
   public Color color {get; set;} 
}

private void ValidateVehicle(IVehicle vehicle)
{
   // Implementation here
}

This obviously require IVehicle to expose all methods and properties that are used by ValidateVehicle.

If the validation logic is different for cars and bikes you should just place the validation method on your vehicle type. This way each vehicle can be validates in their own way.

public interface IVehicle{
    Color color {get; set;}
    bool ValidateVehicle();
}

A third way would be to use type checks:

private void ValidateVehicle(object vehicle)
{
   if(vehicle is Car car){
      ...
   }
   if(vehicle is Bike bike){
      ...
   }
}

But this is not as easy to maintain. Say that you introduce a motorbike, if you use a interface you just need to make your new vehicle inherit that interface, and the compiler complain if you made any mistake. If you use type-checks you need to remember all the various places you check for type and add another check for your motorbike, that can quickly become a maintenance nightmare. Because of this type checks are generally frowned upon.

I'm guessing this is for an assignment, but I dislike examples of object orientation like this. Notably a car is not a wheel, it has wheels, i.e. the wheel should be a property and not inherited.

I generally prefer geometry when demonstrating object orientation, it has plenty of examples of composition and inheritance, and is actually useful in real programs. In contrast, I have difficulty imagining where a vehicle inheritance hierarchy would actually be useful.

JonasH
  • 28,608
  • 2
  • 10
  • 23