【问题标题】:IEnumerable<object> a = new IEnumerable<object>(); Can I do this?IEnumerable<object> a = new IEnumerable<object>();我可以这样做吗?
【发布时间】:2011-01-05 16:19:44
【问题描述】:

我想创建一个对象IEnumerable&lt;object&gt;的新实例

我可以这样做吗?

IEnumerable<object> a = new IEnumerable<object>();

【问题讨论】:

  • 请澄清您的问题。那行代码不会编译,我相信你已经发现了。如果您可以向我们提供有关您实际想要达到的目标的更多信息,那将有助于我们回答您。
  • @WingMan20-10:嗯,这改变了一切。您不能添加到通用 IEnumerable&lt;T&gt;。你必须使用List&lt;T&gt;之类的东西。
  • 在这种情况下,您需要一个具体的数组 List objs = new IEnumerable。您不能将项目添加到迭代器,因为它不是集合......它是一个迭代器:)
  • @ivo:注意IEnumerable&lt;T&gt; 不代表一个迭代器——它代表一个iterable 序列。 IEnumerator&lt;T&gt; 本身代表迭代器。

标签: c#


【解决方案1】:

例如,您可以创建一个List&lt;object&gt; 的实例,它实现了IEnumerable&lt;object&gt;。示例:

List<object> list = new List<object>();
list.Add(1);
list.Add(4);
list.Add(5);

IEnumerable<object> en = list;
CallFunction(en);

【讨论】:

  • 鉴于该问题显示了泛型的使用,给定一个不实现泛型 IEnumerable&lt;T&gt; 的类型示例,IMO 是个坏主意。
  • 使用 CallFunction(list.AsEnumerable()) 代替 IEnumerable en = list;...
  • 如果可能的话,我会使用带有字面初始化程序的数组,它是 .NET 中最有效和最轻量级的可枚举类型,并且没有 List 的开销。仅当您确实需要或想要在初始化后进行变异时才应使用列表。此外,最好在数组或列表上添加 System.Linq 并调用 .AsEnumerable()。
【解决方案2】:

另一种解决方案是使用Empty

msdn extract:

返回具有指定类型参数的空 IEnumerable。

IEnumerable<object> a = Enumerable.Empty<object>();

关于它有一个线程:Is it better to use Enumerable.Empty() as opposed to new List to initialize an IEnumerable?

如果您使用空数组或空列表,则它们是对象,它们存储在内存中。垃圾收集器必须照顾它们。如果您正在处理高吞吐量应用程序,这可能会产生显着影响。

Enumerable.Empty 不会在每次调用时创建一个对象,从而减少了 GC 的负载。

【讨论】:

  • 最干净的答案!
【解决方案3】:

由于您现在指定要添加到它,所以您想要的不是简单的IEnumerable&lt;T&gt;,而是至少一个ICollection&lt;T&gt;。我建议像这样简单地使用List&lt;T&gt;

List<object> myList=new List<object>();
myList.Add(1);
myList.Add(2);
myList.Add(3);

您可以在任何需要 IEnumerable&lt;object&gt; 的地方使用 myList,因为 List&lt;object&gt; 实现了 IEnumerable&lt;object&gt;

(澄清前的旧答案)

您不能创建IEnumerable&lt;T&gt; 的实例,因为它是一个普通接口(有时可以指定默认实现,但通常只与 COM 一起使用)。

所以你真正想要的是实例化一个 class 来实现 interface IEnumerable&lt;T&gt;。行为因您选择的类而异。

对于空序列使用:

IEnumerable<object> e0=Enumerable.Empty<object>();

对于非空可枚举,您可以使用一些实现IEnumerable&lt;T&gt; 的集合。常见的选择是数组T[]List&lt;T&gt;,或者如果你想要不变性ReadOnlyCollection&lt;T&gt;

IEnumerable<object> e1=new object[]{1,2,3};
IEnumerable<object> e2=new List<object>(){1,2,3};
IEnumerable<object> e3=new ReadOnlyCollection(new object[]{1,2,3});

实现IEnumerable&lt;T&gt; 的另一种常见方式是C# 3 中引入的iterator feature

IEnumerable<object> MyIterator()
{
  yield return 1;
  yield return 2;
  yield return 3;
}

IEnumerable<object> e4=MyIterator();

【讨论】:

    【解决方案4】:

    不,你不能,因为IEnumerable 是一个接口。

    您应该能够创建大多数实现IEnumerable 的非接口类型的空实例,例如:-

    IEnumerable<object> a = new object[] { };
    

    IEnumerable<object> a = new List<object>();
    

    【讨论】:

    • @AdamRalph:我投了反对票,然后分心了,所以无法立即发表评论。接口是类型,所以你的答案是危险的错误,因为它传播了一个常见的误解。
    【解决方案5】:

    不,你不能那样做。请改用以下代码行:

    IEnumerable<int> usersIds = new List<int>() {1, 2, 3}.AsEnumerable();
    

    希望对你有帮助。

    【讨论】:

      【解决方案6】:

      主要原因是我们不能创建接口的对象,而IEnumerable是一个接口。 我们需要创建实现接口的类的对象。这是我们不能直接创建 IEnumerable 对象的主要原因。

      【讨论】:

        【解决方案7】:

        你可以这样做:

        IEnumerable<object> list = new List<object>(){1, 4, 5}.AsEnumerable();
        CallFunction(list);
        

        【讨论】:

          【解决方案8】:

          我想创建一个新的可枚举对象或列表并能够添加到它。

          这条评论改变了一切。您不能添加到通用 IEnumerable&lt;T&gt;。如果要保留System.Collections.Generic 中的接口,则需要使用实现ICollection&lt;T&gt; 的类,如List&lt;T&gt;

          【讨论】:

            【解决方案9】:

            没有IEnumerable是一个接口,你不能创建接口的实例

            你可以这样做

            IEnumerable<object> a = new object[0];
            

            【讨论】:

            • 是否可以像@Jon Skeet 那样创建 COM 接口的实例?
            • 我认为可以指定一个实例化的默认实现,而不是 COM 接口的接口。
            • @JonSkeet 说调用new SomeComInterface() 实例化接口的关联“CoClass”而不是实例化接口本身不是更准确吗?
            • @phoog:那是准确的——但重要而奇怪的是,在某些情况下,您可以将new 与接口一起使用。
            【解决方案10】:

            这是一个相当老的问题,但为了新手,这就是我们如何保护IEnumerable&lt;T&gt; 免受null exception 的影响。换句话说,创建一个IEnumerable&lt;T&gt;类型变量的空实例

            public IEnumerable<T> MyPropertyName { get; set; } = Enumerable.Empty<T>();
            

            https://docs.microsoft.com/en-us/dotnet/api/system.linq.enumerable.empty?view=net-5.0

            干杯。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2021-06-30
              • 1970-01-01
              • 2015-06-03
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多