Patrick Skelton Ответов: 3

Как я могу привести запрос LINQ?


Есть ли способ использовать оператор явного приведения, как часть запроса LINQ?

Я попытался показать, что я хочу сделать с приведенным ниже кодом. Это несколько надуманный пример, потому что в реальном приложении автомобиль, вероятно, был бы подклассом транспортного средства, но, пожалуйста, сделайте вид, что по какой-то причине отношения родитель-подкласс не подходят. Кроме того, для простоты предположим, что я знаю, что все транспортные средства - это автомобили.

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;
}

Я изо всех сил пытаюсь написать код, указанный в приведенном выше комментарии. Может ли кто-нибудь помочь мне (если это действительно возможно)?

Я довольно новичок в LINQ, поэтому приношу свои извинения, если ответ на этот вопрос ослепительно очевиден.

Что я уже пробовал:

Я попробовал обычный гугл, но ни один пример, который я смог найти, не имеет точного отношения к тому, что я хочу сделать.

3 Ответов

Рейтинг:
27

F-ES Sitecore

public IList<Car> SomeCars
{
    get
    {
        return _vehicles.Select(v => (Car)v).ToList();
    }
}


Рейтинг:
2

#realJSOP

Попробовать это:

List<Car> cars = carCache.Where(x=>x is Car).ToList<Car>();


OriginalGriff

Тсссс! Это компилируется для вас?

#realJSOP

Я не знаю - я был в середине своей собственной работы и был немного отвлечен.

Рейтинг:
0

OriginalGriff

Лично я бы сделал это немного по-другому:

public class Vehicle
{
}
 
public class Car : Vehicle
{
Это означает, что каждый автомобиль также является транспортным средством, поэтому вы можете хранить все типы транспортных средств в своем кэше:
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); }
     }

(Не храните коллекцию как IEnumerable: у нее нет метода Add, поэтому трудно изменить содержимое!)


Midi_Mick

Это работает, если автомобиль наследуется от автомобиля. Однако его код показывает явное приведение, определенное, так что может быть, что Car является членом Vehicle, и явное приведение возвращает этот член (именно поэтому обычно определяются явные приведения), и в этом случае вышесказанное не сработает. При таких обстоятельствах ему придется опустить слово "где".

OriginalGriff

Отчасти поэтому я бы вывел машину из автомобиля - это заставляет все работать лучше. Если у вас нет подходящего общего корня, вы не можете его разыграть - вам придется создать новый экземпляр и заполнить его соответствующей информацией. Но тогда вы даже получите два разных экземпляра, если разыграете один и тот же автомобиль дважды, так что изменения в одном не повлияют на другой (и последующие изменения в исходном автомобиле не повлияют ни на один экземпляр). Вывод-лучшее решение.

Richard Deeming

Если вы собираетесь добавить наследование, то было бы лучше использовать OfType метод:
return _vehicles.OfType<Car>().ToList();

OriginalGriff

Отличная идея! Я либо совсем забыл его, либо так и не выучил...

Patrick Skelton

Спасибо вам за эти ответы. Я многому научился. Одна вещь, которой я научился,-это выбирать менее запутанные имена, например, классы. Я должен был выбрать что-то другое для "автомобиля" и "транспортного средства", потому что, как я уже упоминал в своем вопросе, эти два типа не имеют отношения между базовым подклассом. Однако я буду знать, что делать, если столкнусь с такой ситуацией. :)