C# 无法将类型 IEnumerable 转换为 List

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11206957/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 16:57:58  来源:igfitidea点击:

Cannot convert type IEnumerable to List

c#

提问by CC Inc

I have been using C# with Unity3d for a few years now, but am just starting with .NET programming. I get the error:

我已经在 Unity3d 中使用 C# 几年了,但我才刚刚开始使用 .NET 编程。我收到错误:

Cannot implicitly convert type 'System.Collections.Generic.IEnumerable<URL>' to 'System.Collections.Generic.List<URL>'. An explicit conversion exists (are you missing a cast?)

无法将类型“ System.Collections.Generic.IEnumerable<URL>”隐式转换为“ System.Collections.Generic.List<URL>”。存在显式转换(您是否缺少演员表?)

Here is my code:

这是我的代码:

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

}

Thanks for any help!

谢谢你的帮助!

采纳答案by archil

You get that error because myClass.GetHistory();returns IEnumerable<URL>, which is not same as List<URL>at compile time, although it is actually List<URL>at runtime. Change method signature to return List<URL>, cause you already do that

你得到这个错误,因为myClass.GetHistory();回报IEnumerable<URL>,这是不一样的List<URL>,在编译的时候,虽然它实际上是List<URL>在运行时。将方法签名更改为 return List<URL>,因为您已经这样做了

public List<URL> GetHistory()

Other workarounds would be to cast method call result to List<URL>

其他解决方法是将方法调用结果转换为 List<URL>

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

Or construct new list from result

或者从结果构建新列表

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

If you do not need List functionality, you could define calledListas IEnumerable

如果不需要 List 功能,可以定义calledList为 IEnumerable

var calledList = myClass.GetHistory();

回答by MBen

Your definition of the GetHistorymethods returns an IEnumerable, and you are assigning it to an IList. Either change the definition , or the usage.

您对GetHistory方法的定义返回一个 IEnumerable,您将它分配给一个 IList。要么改变定义,要么改变用法。

If you don't need to change the collection I would change the definition of GetHistory to IEnumerable.

如果您不需要更改集合,我会将 GetHistory 的定义更改为 IEnumerable。

回答by sll

Here is the error

这是错误

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

Since GetHistorymethod returns IEnumerable<URL>

由于GetHistory方法返回IEnumerable<URL>

public IEnumerable<URL> GetHistory()

EDIT:

编辑:

Solution: just change the return value of GetHistory()method to IList<T>

解决方案:只需将GetHistory()方法的返回值更改为IList<T>

回答by Neil Moss

To get things working you just need to change the return type of your GetHistory() method to List<URL>.

要使事情正常工作,您只需将 GetHistory() 方法的返回类型更改为List<URL>.

You can typecast a List to an IEnumerable, but not the other way around. The compiler is told that GetHistory returns IEnumerable, and even though it isa list, it doesn't know that.

您可以将 List 类型转换为 IEnumerable,但不能反过来。编译器被告知 GetHistory 返回 IEnumerable,即使它一个列表,它也不知道。

回答by Joe

A List is IEnumerable, but the reverse is not true.

列表是 IEnumerable 的,但反之则不然。

If you need list operations, you should change your method to return an IList<> instead of IEnumerable. Alternately, you should assign the return value to an IEnumerable variable instead of a List. This will limit you to (without further manipulation) the IEnumerable methods (you can do a foreach and use LINQ things like .First, but you can't reference by specific position, for example). Which might be enough for what you ultimately need it for.

如果需要列表操作,则应更改方法以返回 IList<> 而不是 IEnumerable。或者,您应该将返回值分配给 IEnumerable 变量而不是列表。这将限制您(无需进一步操作)IEnumerable 方法(例如,您可以执行 foreach 并使用 LINQ 之类的东西,例如 .First,但您不能通过特定位置进行引用)。这可能足以满足您最终需要的用途。

回答by Hamid

just add

只需添加

yield return U;

end of while block and remove

结束while块并删除

 return URLs;

after that function is like this

之后那个功能是这样的

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();


}

回答by Branko Dimitrijevic

In alternative to what others have said, you could simply:

除了其他人所说的,您可以简单地:

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

Since GetHistorymodifies the URLsas its side-effect anyway, there is little purpose of returning any result from it. In addition to that, you might consider whether GetHistoryneeds to be explicitlycalled at all - perhaps the equivalent code should be implicitly executed when the URLsgetter is first called?

由于无论如何都GetHistory将 修改URLs为它的副作用,因此从它返回任何结果几乎没有任何意义。除此之外,您可能会考虑是否GetHistory需要显式调用 - 也许在URLs首次调用 getter时应该隐式执行等效代码?

Also, why aren't you using foreach?

另外,你为什么不使用foreach

回答by Prayan shakya

You can just use tolist() provided by Linq lamda to convert from IEnumerable to List.

您可以使用 Linq lamda 提供的 tolist() 将 IEnumerable 转换为 List。

using System.Linq;

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