从IEnumerator检索原始类型

时间:2018-07-06 01:07:58

标签: c# type-conversion ienumerator

示例-我可以编写一个对列表中每个项目进行收益回报的方法,如下所示:

IEnumerator test1()
{
    List<int> list = new List<int> { 0, 1, 2, 3, 4 };

    foreach (int entry in list)
    {
        yield return entry;
    }
}

它在IEnumerator中返回结果,该IEnumerator将每个结果保存为一个对象。我仍然可以通过转换将整数取回来,就像这样:

IEnumerator testEnumerator = test1();

while (testEnumerator.MoveNext())
{
    int i = Convert.ToInt32(testEnumerator.Current);
    Console.WriteLine(i);
}

但是,如果我用yield return返回的值是我不容易转换为的类型怎么办?

IEnumerator test2()
{
    System.Windows.Controls.CheckBox checkbox1 = new System.Windows.Controls.CheckBox();
    System.Windows.Controls.CheckBox checkbox2 = new System.Windows.Controls.CheckBox();
    System.Windows.Controls.CheckBox checkbox3 = new System.Windows.Controls.CheckBox();
    List<System.Windows.Controls.CheckBox> list = new List<System.Windows.Controls.CheckBox> { checkbox1, checkbox2, checkbox3 };

    foreach (FrameworkElement entry in list)
    {
        yield return entry;
    }
}

此外,如果test2()不一定知道它将返回的类型怎么办?理想情况下,这是一个递归搜索UI元素的可视树并返回[blank]类型的所有子级的函数。但是,调用test2()的人将知道他们应该返回哪种类型。

如何从通用IEnumerator.Current中获取FrameworkElement或Checkbox的实例?

我应该注意,虽然我确实知道在调用它的方法中应该从test2()返回哪种类型,但test2()不一定总是返回该类型。它可以返回任何类型的FrameworkElement,包括TextBox,Grid,Border等。我最好不修改test2()返回的值或至少保持其通用性来做到这一点。

2 个答案:

答案 0 :(得分:2)

您的首选将是使用通用版本IEnumerator<CheckBox>

public static IEnumerator<CheckBox> test1()
{
   CheckBox checkbox1 = new CheckBox();
   CheckBox checkbox2 = new CheckBox();
   CheckBox checkbox3 = new CheckBox();
   List<CheckBox> list = new List<CheckBox> { checkbox1, checkbox2, checkbox3 };

   foreach (var entry in list)
   {
      yield return entry;
   }
}

但是您也可以轻松使用IEnumerable<CheckBox>,它也有其优点(取决于您的需求)

public static IEnumerable<CheckBox> test2()
{
   CheckBox checkbox1 = new CheckBox();
   CheckBox checkbox2 = new CheckBox();
   CheckBox checkbox3 = new CheckBox();
   List<CheckBox> list = new List<CheckBox> { checkbox1, checkbox2, checkbox3 };

   foreach (var entry in list)
   {
      yield return entry;
   }
}

用法

var testEnumerator = test1();

while (testEnumerator.MoveNext())
{
   // i am a CheckBox
   CheckBox checkBox = testEnumerator.Current;

}

foreach (var item in test2())
{
   // i am a CheckBox also
   CheckBox checkBox = item;
}

其他资源

IEnumerable Interface

  

公开枚举器,该枚举器支持对   指定类型的集合。

IEnumerator Interface

  

支持对通用集合进行简单的迭代。

答案 1 :(得分:0)

我知道了(部分基于我在这些评论和答案中看到的一些线索)。

首先,让test2()返回FrameworkElements的IEnumerator而不是通用的IEnumerator:

    IEnumerator<FrameworkElement> test2()
    {
        System.Windows.Controls.CheckBox checkbox1 = new System.Windows.Controls.CheckBox();
        System.Windows.Controls.CheckBox checkbox2 = new System.Windows.Controls.CheckBox();
        System.Windows.Controls.CheckBox checkbox3 = new System.Windows.Controls.CheckBox();
        List<System.Windows.Controls.CheckBox> list = new List<System.Windows.Controls.CheckBox> { checkbox1, checkbox2, checkbox3 };

        foreach (FrameworkElement entry in list)
        {
            yield return entry;
        }
    }

第二,在返回结果后,我可以使用此转换从FrameworkElement切换到更具体的类型:

        IEnumerator<FrameworkElement> testEnumerator2 = test2();

        while (testEnumerator2.MoveNext())
        {
            System.Windows.Controls.CheckBox checkbox = (System.Windows.Controls.CheckBox)testEnumerator2.Current;
            Console.WriteLine(checkbox.IsChecked);
        }