1

I pass a dictionary into a method:

Dictionary<string, object> vehicles

The value of the dictionary can be either a class instance named Vehicle or a class instance that inherits from Vehicle, named Truck.

I have a DataTable that I then use a field row value to extract the dictionary value, using reflection.

Vehicle v = (Vehicle)vehicles[dt.Rows[0]["Reference"].ToString()]

PropertyInfo vehicleInfo = typeof(Vehicle).GetProperty("Height");
string propertyVal = vehicleInfo.GetValue(t, null).ToString();

The only problem is, if I try to extract a field value from the class Truck and the field is not inherited from Vehicle, then vehicleInfo is not an object due to being unable to get the property.

Is there a way I can dynamically access either Vehicle or Truck class properties using the above? Or is a completely different approach required?

2
  • Could you explain why you are using reflection to access properties of Vehicle? Commented Jul 20, 2017 at 15:49
  • 1
    The question really is how do you determine what properties you want to get? That implies knowledge of all these types, which is odd in this semi-disconnected way of accessing them. You've probably got an X/Y problem here. Whatever you're trying to accomplish is most likely better achieved using a different method. Limiting it to this one, you could use the new pattern matching language improvements or the older var xy = x as Y; if(x != null)... BS... Commented Jul 20, 2017 at 15:49

2 Answers 2

2

Ideally you'd want to prevent the problem by ensuring that you already know the type of your objects. If you have an object, you don't know its type, and you have to inspect it to see if it's a Truck or a Vehicle and see which properties it has, that's the underlying problem to solve. You don't want a method to take an object and then try to figure out what it is. Instead, fix it so that the type of the parameter is meaningful and tells the method everything that it needs to know about that parameter.

Without knowing the full details, you could try something like this:

public interface IVehicle
{
    decimal Height {get;}
}

This interface has the properties you expect. You write all your code using this interface.

Dictionary<string, IVehicle> vehicles

From now on, you never have to wonder what something is or which properties it has. It's an IVehicle, which tells you that it has all of the properties of IVehicle.

You still have the original problem - other classes that don't implement this interface. You can adapt then so that they do implement the interface. For example,

public class TruckToVehicleAdapter : IVehicle
{
    private readonly Truck _truck;

    public TruckToVehicleAdapter(Truck truck)
    {
        _truck = truck;
    }

    public decimal Height { get { return _truck.WhateverHeightPropertyThisHas; } }
}

That's just one approach. But the general idea is to avoid having a bunch of objects where you don't know their types. Instead, think of how to take the object you have and require it to be the type you want. Convert it, make a new object, write an adapter like in the above example. But then you'll know what you have.

And if another new type of object comes along you won't have to modify all your methods to see if your object is a Motorcycle or a RecreationalVehicle. That can get out of hand. You can just follow the same pattern. Make everything an IVehicle.

Sign up to request clarification or add additional context in comments.

Comments

1

You could access it like this:

if (vehicle is Truck t)
     // t.FieldOfTruck

In role of vehicle can be even object

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.