2013-03-27 2 views
0

Я имею переменную var, называемую retVal, которая равна некоторому запросу. После некоторых условий я хочу приравнять его к другому запросу. Но я получаю ошибку, например implicit cast of type "System.Collections.Generic.IEnumerable<AnonymousType#1>" in "System.Collections.Generic.IEnumerable<AnonymousType#2>" is impossible. Вы можете спросить меня, почему я не хочу определять другую переменную var. Потому что этот используется в цикле foreach. Давайте посмотрим на код:Как приравнять переменную `var` к другому запросу

var retVal = from groupItem in result.AsEnumerable() 
          where groupItem.Sms.First().amountOfParts == (
           (from item in rawSmsList.AsEnumerable() 
           where item.referenceNumber == groupItem.Sms.First().referenceNumber 
           select item).Count() 
          ) 
          select new 
          { 
           Value = groupItem.Value, 
           Sms = groupItem.Sms 
          }; 
       //CONDITION 
       if (retVal.ToArray().Length==0) 
       { 
        //HERE I NEED TO RETVAL EQUATE NEW QUERY 
        retVal = from groupItem in result.AsEnumerable() 
           where groupItem.Sms.First().amountOfParts == (
            (from item in rawSmsList.AsEnumerable() 
            where item.senderNumber == groupItem.Sms.First().senderNumber 
            select item).Count() 
           ) 
           select new 
           { 
            Value = groupItem.Value, 
            Sms = groupItem.Sms 
           };       
       } 

       foreach (var item in retVal)//FOREACH EXPECTS THE SAME RETVAL!!! 

Так как бросить различные запросы к одной и той же переменной var? Или как найти тип переменной var, а затем применить ее к новой заданной переменной?

ответ

5

var означает неявно введенную переменную, это означает, что ее тип будет определен во время компиляции. Поэтому при первом использовании ему будет назначен анонимный тип, во второй раз вы пытаетесь присвоить ему другой анонимный тип, вы можете Не делай этого.

Вы можете изменить свой код, чтобы использовать класс вместо анонимного объекта, а затем проецировать на него, тогда вы будете делать то, что делаете сейчас. Вы можете создать класс, как:

public class MyClass 
{ 
    public int Value {get;set;} 
    public string Sms {get;set;} 
} 

, а затем проецировать его путем изменения оператора выбора, как:

var retVal = ...... 
      select new MyClass 
       { 
        Value = groupItem.Value, 
        Sms = groupItem.Sms 
       }; 
+0

Возможно, здесь можно использовать ['SequenceEqual'] (http://msdn.microsoft.com/en-us/library/bb342073.aspx) для сравнения результатов двух анонимных типизированных результатов. –

+0

@JonathonReinhart, я думаю, что equate OP означает присвоить результат нового запроса существующему 'retVal', его запутанному, но из кода, который кажется таким – Habib

+0

Нет никакого способа отбросить один анонимный тип другому? – Nolesh

3

Анонимный класс вы используете для ваших прогнозов выглядит одинаково с нами, но они 'Два разных класса в отношении компилятора, поэтому в этой ошибке вы увидите AnonymousType # 1 и AnonymousType # 2.

Одним из решений является просто выбрать «groupItem» вместо проецирования анонимным классом, поскольку вы используете только свойства внутри самого элемента groupItem. Это даст вам тот же тип IQueryable.

Side Примечание: вы должны заменить "retVal.ToArray() Длина == 0." С

+0

Спасибо за внимание! +1 – Nolesh

3

Чтобы добавить ответ Хабиба "retVal.Any()!":

Просто создать реальный класс вместо использования анонимного типа (который является другим классом при каждом его использовании). Я не знаю, виды из вашего примера, так что вы должны будете указать:

public class ValueSmsThing   // Give it a better name! 
{ 
    public IDontKnow Value { get; private set; } // specify the type! 
    public SmsNumber Sms { get; private set; } // !! 

    public ValueSmsThing(IDontKnow value, SmsNumber sms) { 
     Value = value; 
     Sms = sms; 
    } 
} 

, а затем в запросе, вместо того, чтобы использовать анонимный тип:

select new 
{ 
    Value = groupItem.Value, 
    Sms = groupItem.Sms 
}; 

Используйте конкретный класс, который вы создано

select new ValueSmsThing(groupItem.Value, groupItem.Sms); 

Тогда ваш for цикл будет знать, перебрать ValueSmsThing с.

+1

+1 Джонатан, просто добавил подобный подход в свой ответ :) – Habib

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