【问题标题】:How to create a custom foreach loop?如何创建自定义 foreach 循环?
【发布时间】:2020-06-17 15:41:15
【问题描述】:

我目前正在尝试了解如何使用 IEnumerable 和 IEnumerator 接口。简而言之,我需要创建一个自定义 foreach 循环,将每个“1”元素替换为“0”。这是仍然不替换任何元素并且仍然打印相同值的代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Test : MonoBehaviour, IEnumerator, IEnumerable
{
   private IEnumerator _enumerator;

   private readonly List<int> _nums = new List<int>{1, 2 ,4};
   private int _position = -1;

   public IEnumerator GetEnumerator()
   {
      return _nums.GetEnumerator();
   }

   public bool MoveNext()
   {
      if (_position < _nums.Count - 1)
      {
         _position++;
         return false;
      }
      return true;
   }

   public void Reset()
   {
      _position = -1;
   }

   public object Current
   {
      get {
         if (_nums[_position] == 1)
         {
            return 0; 
         }
         return _nums[_position];
      }
   }

   private void Start()
   {
      foreach (var i in _nums)
      {
         Debug.Log(_nums[i]);
      }
   }
}

我将不胜感激:P

【问题讨论】:

  • 有点不清楚您要做什么以及“自定义 foreach 循环”是什么意思。这似乎是一个 X/Y 问题。您是否想通过您的_nums 枚举返回0 来代替1 但又不改变原始_nums
  • 另外,我认为您在 MoveNext 中的返回值已反转。如果没有更多项目,它应该返回false

标签: c# loops for-loop unity3d foreach


【解决方案1】:

看起来您正在尝试做的只是迭代一个序列,将 1 替换为 0。在这种情况下,将其包装在一个执行 yield return 的方法中会更容易:

IEnumerable<int> GetValues(IEnumerale<int> source)
{
  foreach(var value in source)
  {
    if(value == 1)
    {
      yield return 0;
    }
    else
    {
      yield return value;
    }
  }
}

现在如果你有:

List<int> _nums = new List<int>{1, 2 ,4};

那么你可以说:

foreach(var value in GetValues(_nums))
{
  Console.WriteLine(value);
}

您也可以使用 Select 方法对 Linq 执行此操作:

foreach(var value in _nums.Select(v => v == 1 ? 0 : v))
{
  Console.WriteLine(value);
}

【讨论】:

    猜你喜欢
    • 2017-11-09
    • 2017-01-29
    • 1970-01-01
    • 1970-01-01
    • 2018-09-21
    • 2019-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多