我需要设置表单上每个文本框的高度,其中一些文本框嵌套在其他控件中.我以为我可以这样做:
private static IEnumerator<TextBox> FindTextBoxes(Control rootControl)
{
foreach (Control control in rootControl.Controls)
{
if (control.Controls.Count > 0)
{
// Recursively search for any TextBoxes within each child control
foreach (TextBox textBox in FindTextBoxes(control))
{
yield return textBox;
}
}
TextBox textBox2 = control as TextBox;
if (textBox2 != null)
{
yield return textBox2;
}
}
}
Run Code Online (Sandbox Code Playgroud)
像这样使用它:
foreach(TextBox textBox in FindTextBoxes(this))
{
textBox.Height = height;
}
Run Code Online (Sandbox Code Playgroud)
但是编译器当然会吐出它的假,因为foreach期望IEnumerable而不是IEnumerator.
有没有办法在不必使用GetEnumerator()方法创建单独的类的情况下执行此操作?
关于"可能存在多个枚举"的SO有一个问题,但这个问题更具体.
请考虑以下方法,该方法接受IEnumerable<string>输入并对其每个元素执行给定方法:
public static bool SomeMethod(IEnumerable<string> enumerable)
{
if (enumerable.IsNullOrEmpty())
{
// throw exception.
}
else
{
return (enumerable.All(SomeBooleanMethod));
}
}
Run Code Online (Sandbox Code Playgroud)
在上面的代码中,IsNullOrEmpty只是一个运行的扩展方法
return (!ReferenceEquals(enumerable, null) || enumerable.Any());
Run Code Online (Sandbox Code Playgroud)
问题是ReSharper警告我"IEnumerable的可能的多个枚举",我真的不知道这是否真的是一个问题.
我理解警告的含义,但是如果你真的需要在无效或空洞的情况下检查并抛出异常,你在这种情况下真的可以做些什么?
我IEnumberable收集了一些物品.我用来.Single()在集合中找到一个特定的对象.
我选择使用Single()因为只应该有一个特定的项目.但是,如果一个不存在,那么我需要创建它并将其添加到集合中.
我的问题是,Single()如果没有与谓词匹配的项目或者有多个项目,则会抛出相同的错误.我的想法是将Single()调用置于try中并捕获异常,添加项目,然后继续.但是,由于两个场景都抛出了InvalidOperationException,我怎么能判断它是由于没有物品还是多个物品?
我知道我可以使用,First()但这并没有强制说应该只有一个(没有做额外的工作).
我也可以Count()在Single()通话前使用,但这似乎只是破坏了重点Single()
我正在尝试在IEnumerable上应用Seq函数.更具体地说,它是System.Windows.Forms.HtmlElementCollection实现ICollection和IEnumerable.
由于F#seq是IEnumerable,我以为我可以写
let foo = myHtmlElementCollection |> Seq.find (fun i -> i.Name = "foo")
Run Code Online (Sandbox Code Playgroud)
但编译器将没有它,并抱怨"类型'HtmlElementCollection'与类型'seq <'a>'"不兼容.
但是,编译器愿意在for .. in ..序列表达式中接受IEnumerable :
let foo = seq { for i in myHtmlElementCollection -> i } |> Seq.find (fun i -> i.Name = "foo")
Run Code Online (Sandbox Code Playgroud)
为了让IEnumerable像任何旧的F#一样被处理,我需要做什么seq?
注意:这个问题被标记为重复,但事实并非如此.链接的"重复"是关于无类型序列(来自seq {for ...}表达式的seq),而我的问题是关于类型化序列.
我有两个列表,我想比较它们并得到差异,而忽略任何案例差异.
我使用以下代码来获取两个列表之间的差异,但它不会忽略大小写差异.
IEnumerable<string> diff = list1.Except(list2);
List<string> differenceList = diff.ToList<string>();
Run Code Online (Sandbox Code Playgroud)
我试过这个:
IEnumerable<string> diff = list1.Except(list2, StringComparison.OrdinalIgnoreCase);
Run Code Online (Sandbox Code Playgroud)
但是,除了似乎没有这种类型的字符串案例检查(所以错误).我希望有一个解决方法.
是否有一个简单的内置方法来获取IEnumerables 的有序列表并返回一个单元IEnumerable,它按顺序产生第一个中的所有元素,然后是第二个,依此类推.
我当然可以写自己的,但我想知道在我做之前是否已经有办法完成这个看似有用的任务.
我在这里有一个情况,我需要继承自己的类List<ItemType>,但是当我这样做时,XmlSerializer不会序列化我的类中声明的任何属性或字段,以下示例演示:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
DoSerialize();
}
private void DoSerialize()
{
MyClass obj = new MyClass();
obj.Add(1);
obj.Add(2);
obj.Add(3);
XmlSerializer s = new XmlSerializer(typeof(MyClass));
StringWriter sw = new StringWriter();
s.Serialize(sw, obj);
}
}
[Serializable]
[XmlRoot]
public class MyClass : List<int>
{
public MyClass()
{
}
int myAttribute = 2011;
[XmlAttribute]
public int MyAttribute
{
get
{
return myAttribute;
}
set
{
myAttribute = value;
}
}
}
Run Code Online (Sandbox Code Playgroud)
结果XML:
<?xml version="1.0" encoding="utf-16"?> …Run Code Online (Sandbox Code Playgroud) 最终编辑:
我选择了Timothy的答案,但如果你想要一个利用C#yield语句的可行实现,请检查Eamon的答案:https://stackoverflow.com/a/19825659/145757
默认情况下,LINQ查询是延迟流式传输的.
ToArray/ ToList给予完全缓冲,但首先他们渴望,其次可能需要相当长的时间来完成无限序列.
有没有办法将这两种行为结合起来:生成时动态流式传输和缓冲值,以便下一次查询不会触发已经查询过的元素的生成.
这是一个基本用例:
static IEnumerable<int> Numbers
{
get
{
int i = -1;
while (true)
{
Console.WriteLine("Generating {0}.", i + 1);
yield return ++i;
}
}
}
static void Main(string[] args)
{
IEnumerable<int> evenNumbers = Numbers.Where(i => i % 2 == 0);
foreach (int n in evenNumbers)
{
Console.WriteLine("Reading {0}.", n);
if …Run Code Online (Sandbox Code Playgroud) 我正在尝试实现一个连接多个Lists 的方法
List<string> l1 = new List<string> { "1", "2" };
List<string> l2 = new List<string> { "1", "2" };
List<string> l3 = new List<string> { "1", "2" };
var result = Concatenate(l1, l2, l3);
Run Code Online (Sandbox Code Playgroud)
但我的方法不起作用:
public static IEnumerable<T> Concatenate<T>(params IEnumerable<T> List)
{
var temp = List.First();
for (int i = 1; i < List.Count(); i++)
{
temp = Enumerable.Concat(temp, List.ElementAt(i));
}
return temp;
}
Run Code Online (Sandbox Code Playgroud) 从C#中的Enumerable中获取精确x值的最佳方法是什么?如果我像这样使用Enumerable .Take():
var myList = Enumerable.Range(0,10);
var result = myList.Take(20);
Run Code Online (Sandbox Code Playgroud)
结果只有10个元素.
我想用默认值填充缺少的条目.像这样的东西:
var myList = Enumerable.Range(0,10);
var result = myList.TakeOrDefault(20, default(int)); //Is there anything like this?
Run Code Online (Sandbox Code Playgroud)
在C#中是否有这样的功能,如果没有,那么实现这一目标的最佳方法是什么?