Is there a way to yield, emit or otherwise materialize a previously empty array in C# / LINQ?
我有一个带有动态字符串数组的对象,我实现如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 | public class MyThing { public int NumberOfThings { get; set; } public string _BaseName { get; set; } public string[] DynamicStringArray { get { List<string> dsa = new List<string>(); for (int i = 1; i <= this.NumberOfThings; i++) { dsa.Add(string.Format(this._BaseName, i)); } return dsa.ToArray(); } } } |
我之前尝试过稍微冷静一点,实现一些在Linq中自动创建格式化数组列表的功能,但我还是失败了。
作为我尝试的一个例子:
1 2 3 4 5 6 | int i = 1; // create a list with a capacity of NumberOfThings return new List<string>(this.NumberOfThings) // create each of the things in the array dynamically .Select(x => string.Format(this._BaseName, i++)) .ToArray(); |
在这种情况下,它实际上并不十分重要,从性能上讲,它可能更糟,但我想知道在LINQ扩展中是否有一种很酷的方法来构建或发出数组。
将范围的帮助吗? </P >
1 2 3 4 | return Enumerable .Range(1, this.NumberOfThings) .Select(x => string.Format(this._BaseName, x)) .ToArray(); |
在"A d Rather redesign片的解决方案: </P >
1 2 3 4 5 6 7 8 9 10 11 12 | public class MyThing { ... // Note IEnumerable<String> instead of String[] public IEnumerable<String> DynamicString(int numberOfThings) { if (numberOfThings < 0) throw new ArgumentOutOfRangeException("numberOfThings"); for (int i = 0; i < numberOfThings; ++i) yield return string.Format(this._BaseName, i + 1); } } |
whenever你想说的,一个阵列,你可以轻易地obtain信息: </P >
1 2 3 | MyThing thing = ...; // Add .ToArray() to have an array String[] myArray = thing.DynamicString(18).ToArray(); |
但whenever所有你想要的只是环没有要创建的阵列或战略(materialize(结果) </P >
1 2 3 4 | // no materialization: no array of 1000000 items foreach (String item in thing.DynamicString(1000000)) { ... } |
你的财产返回西安IEnumerable可以和你那么不退化的toarray(电机)的推广,如果你必要的"。 </P >
1 2 3 4 5 6 7 8 | public string[] DynamicStringArray { get { for (int i=1; i <= this.NumberOfThings; i++) yield return string.Format(this._BaseName, i); } } |
然而,inherently yields是缓慢的,因为那是上下文切换的GOES ON。你是更好地做这断: </P >
1 2 3 4 5 6 7 8 9 10 11 12 | public string[] DynamicStringArray { get { string[] result = new string[this.NumberOfThings]; for (int i = 0; i < this.NumberOfThings; i++) { result[i] = string.Format(this._BaseName, i + 1)); } return result; } } |
那些LINQ扩展方法是很好的感觉,当你的懒惰。但如果你需要它给perform阱你应该避免他们。 </P >