Click here to Skip to main content
15,881,882 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Is there a way to use an explicit cast operator as a part of a LINQ query?

I have tried to show what I want to do with the code below. It is a somewhat contrived example because in a real application a Car would probably be a subclass of a Vehicle, but please pretend that for some reason a parent-subclass relationship is not appropriate. Also, for the sake of simplicity, assume I know all the vehicles are cars.

C#
public class Vehicle
{
}

public class Car
{
    public static explicit operator Car( Vehicle v )
    {
    }
}

public CarCache
{
    public IList<car> SomeCars
    {
        get
        {
            // Can I use a single LINQ query here to return the vehicles as cars? 
        }
    }

    private IEnumerable<vehicle> _vehicles;
}

I'm struggling to write the code indicated by the comment above. Can anyone help me out (if it is indeed possible)?

I'm fairly new to LINQ, so I apologise if the answer to this question is blindingly obvious.

What I have tried:

I have tried the usual Googling but no example I have been able to find seems to relate exactly to what I want to do.
Posted
Updated 16-Nov-16 6:17am

C#
public IList<Car> SomeCars
{
    get
    {
        return _vehicles.Select(v => (Car)v).ToList();
    }
}
 
Share this answer
 
Try this:

C#
List<Car> cars = carCache.Where(x=>x is Car).ToList<Car>();
 
Share this answer
 
v2
Comments
OriginalGriff 16-Nov-16 11:58am    
Psst! Does that compile for you?
#realJSOP 16-Nov-16 18:09pm    
I dunno - I was in the middle on own work, and was kinda distracted.
Personally, I'd do it slightly differently:
C#
public class Vehicle
{
}
 
public class Car : Vehicle
{
What that means is that every Car is also a Vehicle, so you can store all Vehicle types in your cache:
C#
public class CarCache
     {
     public IList<Car> SomeCars
         {
         get
             {
             return _vehicles.Where(v => v is Car).Cast<Car>().ToList();
             }
         }
     private List<Vehicle> _vehicles = new List<Vehicle>();
     public void Add(Vehicle v) { _vehicles.Add(v); }
     }

(Don't store the collection as an IEnumerable: it doesn't have an Add method so it's difficult to change the content!)
 
Share this answer
 
Comments
Midi_Mick 16-Nov-16 12:16pm    
That works if Car inherits from Vehicle. However, his code shows an explicit cast defined, so it may be that Car is a member of Vehicle, and the explicit cast returns that member (which is why explicit casts are normally defined), in which case the above won't work. He'd need to leave out the "Where" under those circumstances.
OriginalGriff 16-Nov-16 12:29pm    
That's partly why I'd derive the Car from the Vehicle - it makes everything work better. If you don't have a suitable root in common, you can't cast it - you'd have to create a new instance and populate it with the relevant info. But then, you'd even up with two different instances if you cast the same vehicle twice, so changes to one won't affect the other (and subsequent changes to the original vehicle won't affect either instance). Deriving is a better solution.
Richard Deeming 16-Nov-16 13:42pm    
If you're going to add inheritance, it would be better to use the OfType method:
return _vehicles.OfType<Car>().ToList();
OriginalGriff 16-Nov-16 14:03pm    
Excellent idea! I had either forgotten it completely or never learned that one... :O
Patrick Skelton 17-Nov-16 5:27am    
Thank you for those replies. I have learnt a lot. One thing I have learnt is to choose less-confusing names for example classes. I should have chosen something different to 'Car' and 'Vehicle' because, as I mention in my question, the two types don't have a base-subclass relationship. I will know what to do if I do encounter that situation though. :)

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