【问题标题】:How to populate an IEnumerable with consecutive uints如何用连续的 uint 填充 IEnumerable
【发布时间】:2012-11-27 22:45:52
【问题描述】:

这是生成连续uints 列表的干净且正确的方法吗?

演员表看起来有点难看,但我是初学者……可能有一种方法不用四处转换?

public class Test
{
    static readonly IEnumerable<uint> AvailableChannels 
         = (IEnumerable<uint>)Enumerable.Range(1,1000);
}

【问题讨论】:

  • 你试过了吗?这会引发异常:ideone.com/dGkrvr
  • @Henrik:是的,我确实尝试了很多......但这是一个缩写示例,我没有编译。抱歉,如果有编译错误,但我想你明白我的意思。

标签: c#


【解决方案1】:
static readonly IEnumerable<uint> AvailableChannels 
     = Enumerable.Range(1,1000)
       .Select(i => (uint)i)
       .ToList();

虽然它仍然是一个演员......

编辑
.ToList() 是这样的,所以每次循环遍历它时都不需要重新创建完整的列表。 (好吧,1000 个 uint 并不多,但这是它的原则 - 如果它们是类,您每次都会创建新的类并得到意想不到的结果,例如丢失的更改)

EDIT2
Cast&lt;uint&gt;() 在运行时不起作用(“指定的转换无效”)。更改为 .Select 以执行演员表。

【讨论】:

  • 所以演员从前到后移动,但我还有一个额外的ToList() 电话。我的答案对解决方案有什么改进?我就是想明白!
  • 我很想知道这是否会比一次性转换序列产生更多或更少的开销,但除此之外,这仍在使用转换。 (编辑:假设单一演员通过协方差工作。也许不是。)
  • 解决方案编译但使用 Visual Studio 2010 引发运行时异常“指定的转换无效”。任何想法为什么?
  • @RonaldMcBean - 我没想到会这样。更正了示例代码并进行了测试。
  • 如果我需要大于int 的数字,现在该怎么办?这就是有时使用uint 的全部原因。
【解决方案2】:

您可以编写自己的可枚举方法:

public static IEnumerable<uint> Foo(
    uint startValue =0, 
    uint maxValue = uint.MaxValue
    )
{
    uint index = startValue;
    while(index < maxValue) {
        yield return index++;
    }
}

public static void Main()
{
    var myUints = Foo().Take(100);
    var myUints2 = Foo(startValue:0, maxValue:1000);
    var myUints3 = Foo(0, 1000);
    foreach(uint x in myUints) {
        Console.WriteLine(x);
    }
}

附注:如果性能是您的应用程序中的一个关键点,您可以阅读这个问题:Why is Enumerable.Range faster than a direct yield loop?(尤其是标记为答案的答案)

【讨论】:

  • 你是对的。我添加了一个maxValue 参数以使其更加明确,即使Take 扩展方法可以完成这项工作
  • 来吧,伙计,您已经完成了大部分工作,只需添加一个start 值:D
  • @RonaldMcBean:复杂性隐藏在 once 方法中。所有消费者代码都不需要担心实现。此外,您不必使用默认参数的值。您可以要求始终传递范围的上限和下限,具体取决于方法的使用情况。
猜你喜欢
  • 1970-01-01
  • 2010-12-30
  • 2023-02-09
  • 1970-01-01
  • 2013-09-02
  • 1970-01-01
  • 2011-07-11
  • 1970-01-01
  • 2020-01-24
相关资源
最近更新 更多