2012-06-26 2 views
4

Я использую C# с Unity3d уже несколько лет, но только начинаю с программирования .NET. Я получаю сообщение об ошибке:Невозможно преобразовать тип IEnumerable в список

Невозможно неявно преобразовать тип 'System.Collections.Generic.IEnumerable<URL>' в 'System.Collections.Generic.List<URL>'. Явное преобразование существует (вы пропали без вести броска?)

Вот мой код:

namespace TestBrowserHistory 
{ 
    public class Test1 
    { 
     public Test1() 
     { 

     } 
      static void Main() 
    { 
     InternetExplorer myClass = new InternetExplorer(); 
     List<URL> calledList = myClass.GetHistory(); 
     Console.WriteLine("Hello!"); 
     Console.WriteLine(calledList[1]); 
     Console.ReadLine(); 
    } 
    } 
} 

public class InternetExplorer 
{ 
    // List of URL objects 
    public List<URL> URLs { get; set; } 
    public IEnumerable<URL> GetHistory() 
    { 
     // Initiate main object 
     UrlHistoryWrapperClass urlhistory = new UrlHistoryWrapperClass(); 

     // Enumerate URLs in History 
     UrlHistoryWrapperClass.STATURLEnumerator enumerator = 
              urlhistory.GetEnumerator(); 

     // Iterate through the enumeration 
     while (enumerator.MoveNext()) 
     { 
      // Obtain URL and Title 
      string url = enumerator.Current.URL.Replace('\'', ' '); 
      // In the title, eliminate single quotes to avoid confusion 
      string title = string.IsNullOrEmpty(enumerator.Current.Title) 
         ? enumerator.Current.Title.Replace('\'', ' ') : ""; 

      // Create new entry 
      URL U = new URL(url, title, "Internet Explorer"); 

      // Add entry to list 
      URLs.Add(U); 
     } 

     // Optional 
     enumerator.Reset(); 

     // Clear URL History 
     urlhistory.ClearHistory(); 

     return URLs; 
    } 

} 

Спасибо за любую помощь!

+0

Привет! Может быть, вы можете быть немного более конкретными: где вы получаете эту ошибку? Нам не нужен источник всего вашего проекта для такой ошибки компиляции. – Kek

+0

Возможный дубликат [IEnumerable в список ] (http://stackoverflow.com/questions/10406410/ienumerablet-to-listt) – dash

+0

И дублируется здесь тоже: http://stackoverflow.com/questions/961375/casting -ienumerablet-to-listt – dash

ответ

7

Вы получаете эту ошибку, потому что myClass.GetHistory(); возвращается IEnumerable<URL>, что не так же, как и List<URL> во время компиляции, хотя это на самом деле List<URL> во время выполнения. Изменить метод подписи для возврата List<URL>, потому что вы уже делаете, что

public List<URL> GetHistory() 

Другие обходные бы бросить результат вызова метода к List<URL>

List<URL> calledList = (List<URL>)myClass.GetHistory(); 

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

List<URL> calledList = new List<URL>(myClass.GetHistory()); 

Если вам не нужны функции списка, вы можете определить calledList как IEnumerable

var calledList = myClass.GetHistory(); 
+4

Или вы можете вызвать .ToList() в перечислимом. – CMircea

3

Ваше определение методов GetHistory возвращает IEnumerable, и вы назначаете его IList. Либо измените определение, либо использование.

Если вам не нужно менять коллекцию, я бы изменил определение GetHistory на IEnumerable.

1

Здесь ошибка

List<URL> calledList = myClass.GetHistory(); 

Поскольку GetHistory метод возвращает IEnumerable<URL>

public IEnumerable<URL> GetHistory() 

EDIT:

Решение: просто изменить возвращаемое значение GetHistory() метода IList<T>

+0

Интересно, почему этот ответ был занижен? – sll

+0

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

+0

Какой из существующих? – sll

1

Чтобы получить работу, вам просто нужно изменить возвращаемый тип метода GetHistory() на List<URL>.

Вы можете привнести список List в IEnumerable, но не наоборот. Компилятору говорят, что GetHistory возвращает IEnumerable, и хотя он является списком, он этого не знает.

1

Список имеет значение IEnumerable, но обратное неверно.

Если вам нужны операции с списком, вы должны изменить свой метод, чтобы вернуть IList <> вместо IEnumerable. В качестве альтернативы вы должны назначить возвращаемое значение переменной IEnumerable вместо List. Это ограничит (без дополнительных манипуляций) методы IEnumerable (вы можете сделать foreach и использовать такие вещи LINQ.Во-первых, но вы не можете ссылаться на определенную позицию, например). Который может быть достаточно для того, в чем вы в конечном счете нуждаетесь в этом.

0

просто добавить

yield return U; 

конец в то время как блок и удалить

return URLs; 

после этого функция как этот

public IEnumerable<URL> GetHistory() 
{ 
    // Initiate main object 
    UrlHistoryWrapperClass urlhistory = new UrlHistoryWrapperClass(); 

    // Enumerate URLs in History 
    UrlHistoryWrapperClass.STATURLEnumerator enumerator = 
             urlhistory.GetEnumerator(); 

    // Iterate through the enumeration 
    while (enumerator.MoveNext()) 
    { 
     // Obtain URL and Title 
     string url = enumerator.Current.URL.Replace('\'', ' '); 
     // In the title, eliminate single quotes to avoid confusion 
     string title = string.IsNullOrEmpty(enumerator.Current.Title) 
        ? enumerator.Current.Title.Replace('\'', ' ') : ""; 

     // Create new entry 
     URL U = new URL(url, title, "Internet Explorer"); 

     // Add entry to list 
     URLs.Add(U); 
     yield return U; 
    } 

    // Optional 
    enumerator.Reset(); 

    // Clear URL History 
    urlhistory.ClearHistory(); 


} 
1

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

GetHistory(); 
List<URL> calledList = URLs; 

В связи с тем, что GetHistory модифицирует URLs как его побочный эффект, мало что значит вернуть какой-либо результат из него. В дополнение к этому вы можете подумать о том, должно ли GetHistory быть явно, вызванное вообще - возможно, эквивалентный код должен быть неявным образом выполняться при первом вызове getter URLs?

Кроме того, почему вы не используете foreach?

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