2009-07-09 2 views
3

Я Linq noobie, может быть, кто-то может указать мне в правильном направлении. Что здесь не так? У этих анонимных типов есть одинаковые подписи.Linq, VB - Анонимный тип не может быть преобразован в анонимный тип

  '*** Get all of the new list items' 
      Dim dsNewFiles = From l1 In list1 _ 
          Where Not (From l2 In list2 _ 
             Select l2.id, l2.timestamp).Contains(New With {l1.id, l1.timestamp}) 

Я хотел было каким-то образом выделить в коде выше, но я получаю ошибку компиляции:

Value of type '<anonymous type> (line n)' cannot be converted to '<anonymous type> (line n)'. 

на».Contains (Новый С {l1.id, l1. timestamp}) «

Я предполагаю, что он считает, что анонимные типы в некотором роде разные, но столбцы id и timestamp одинаковы в любом списке. Они также находятся в одном порядке. Что еще может быть разным между этими двумя?

[Редактировать 7/10/2009 16:28 EST]

Я попробовал предложенный код от пользователя Meta-Knight (Новые С {Key l1.id, l1.timestamp}), и констатировала ошибка компиляции. Однако, когда я побежал код с List1 и List2 следующим образом:

List1       List2 
id  timestamp    id  timestamp 
--  ----------    --  ---------- 
01  2009-07-10 00:00:00 01  2009-07-10 00:00:00 

Результат был:

dsNewFiles 
id  timestamp 
--  ---------- 
01  2009-07-10 00:00:00 

Он должен был пустой список.

ответ

1

Просто измените последнюю часть вашего кода:

New With {Key l1.id, Key l1.timestamp} 

Я проверил код и он работает.

Edit:

Я не знаю, почему это не работает для вас, я выложу весь код просто чтобы быть уверенным.

Dim dsNewFiles = From l1 In list1 _ 
          Where Not (From l2 In list2 _ 
             Select l2.ID, l2.TimeStamp).Contains(New With {Key l1.ID, Key l1.TimeStamp}) 

Другим вариантом является просто сделать следующее:

Dim dsNewFiles = list1.Except(list2) 

Для этого, чтобы работать, ваш класс должен переопределить Equals и GetHashCode, и реализовать IEquatable (Of T) интерфейс. Там очень хороший пример on MSDN (внизу).

Если идентификатор и период времени не представляют собой равенство в вашем классе, вы можете использовать пользовательский IEqualityComparer (Of T) в качестве второго аргумента.

+0

@ Мета-рыцарь: Спасибо за понимание. Ошибка компиляции исчезла. Однако код по-прежнему не работает, как ожидалось. См. Изменение выше. – Daniel

+0

Я отредактировал более подробную информацию и другую альтернативу. –

1

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

Class A 
BeginClass 
    Begin ID as Int Begin ... End 
    Stuff as String Begin ... End 
EndClass 

Class B 
BeginClass 
    Begin Stuff as String Begin ... End 
    ID as Int Begin ... End 
EndClass 

From a In someListofAs 
Where Not (From b In someListofBs Select b).Contains(a) 

Полный код аэропорта, кстати.

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

Попробуйте это:

From l1 In list1 _ 
Where Not (From l2 In list2 _ 
    Select New With { ID = l2.id, Timestamp = l2.timestamp}).Contains(
     New With { ID = l1.id, Timestamp = l1.timestamp}) 
+0

Ах. Понимаю. Любая идея, как делать то, что я пытаюсь сделать там? – Daniel

+0

Я вижу ваше редактирование там ... Я не думаю, что это сработает, по крайней мере, похоже, это не так. Разве это не тот же случай, что и выше? Оба новых «Света» создадут объекты разных подписей? – Daniel

+0

@hypoxide Ни одна из подписей не выглядит одинаково для меня. Если я не ошибаюсь, что я не вижу. Попробуйте и посмотрите, что вы получите, у меня нет VS передо мной, иначе я бы попробовал. – Joseph

Смежные вопросы