[英]Passing a value by ref to an IENumerator function?
为了澄清我正在Unity3D中执行此操作,这可能很重要,也可能并不重要?
我试图找出是否可以通过ref将值传递给不屈服的IEnumerator函数。 如果我尝试使用可产生收益的函数来执行此操作,则VS2010会抱怨(“迭代器不能具有ref或out参数”),但是,如果我使用类似的IEnumerator函数将调用包装起来,该函数调用了产生函数,但不会产生自身,错误消失了,事情似乎开始起作用。 我试图找出我是否处于意外行为状态,或者这是否是正常行为。
这是我正在做的事的一个例子:
IEnumerator Wrapper(ref int value)
{
int tmp = ++value; // This is the ONLY place I want the value
return Foo(tmp); // of the ref parameter to change!
} // I do _NOT_ want the value of the ref
// parameter to change in Foo()!
IENumerator Foo(int value)
{
// blah blah
someFunc(value);
someSlowFunc();
yield return null;
yield return null;
}
看起来不错。 top函数仅返回IEnumerator-否则为普通函数。 最底层的函数是 IEnumerator [由编译器转换为时髦的类],因此不能具有ref值。
顶层函数可以这样写:
void Wrapper(ref int value, out IEnumerator coroutine)
{
int tmp = ++value;
coroutine = Foo(tmp);
}
这有点混乱-但它说明了这是处理两个数据的普通函数。 通过引用传递的int,以及它返回的IEnumerator [只是一个类](在此示例中,通过使用out)。
补充:这是幕后工作原理:
static void Main(string[] args)
{
//Lets get the 'IEnumerable Class' that RandomNum gets compiled down into.
var IEnumeratorClass = RandomNum(10, 10);
//All an IEnumerable is is a class with 'GetEnumerator'... so lets get it!
var IEnumerableClass = IEnumeratorClass.GetEnumerator();
//It can be used like so:
while (IEnumerableClass.MoveNext())
{
Console.WriteLine(IEnumerableClass.Current);
}
Console.WriteLine(new String('-', 10));
//Of course, that's a lot of code for a simple job.
//Luckily - there's some nice built in functionality to make use of this.
//This is the same as above, but much shorter
foreach (var random in RandomNum(10, 10)) Console.WriteLine(random);
Console.WriteLine(new String('-', 10));
//These simple concepts are behind Unity3D coroutines, and Linq [which uses chaining extensively]
Enumerable.Range(0, 100).Where(x => x % 2 == 0).Take(5).ToList().ForEach(Console.WriteLine);
Console.ReadLine();
}
static Random rnd = new Random();
static IEnumerable<int> RandomNum(int max, int count)
{
for (int i = 0; i < count; i++) yield return rnd.Next(i);
}
//This is an example of what the compiler generates for RandomNum, see how boring it is?
public class RandomNumIEnumerableCompiled : IEnumerable<int>
{
int max, count;
Random _rnd;
public RandomNumIEnumerableCompiled(int max, int count)
{
this.max = max;
this.count = count;
_rnd = rnd;
}
IEnumerator IEnumerable.GetEnumerator()
{
return new RandomNumIEnumeratorCompiled(max, count, rnd);
}
IEnumerator<int> IEnumerable<int>.GetEnumerator()
{
return new RandomNumIEnumeratorCompiled(max, count, rnd);
}
}
public class RandomNumIEnumeratorCompiled : IEnumerator<int>
{
int max, count;
Random _rnd;
int current;
int currentCount = 0;
public RandomNumIEnumeratorCompiled(int max, int count, Random rnd)
{
this.max = max;
this.count = count;
_rnd = rnd;
}
int IEnumerator<int>.Current { get { return current; } }
object IEnumerator.Current { get { return current; } }
public bool MoveNext()
{
if (currentCount < count)
{
currentCount++;
current = rnd.Next(max);
return true;
}
return false;
}
public void Reset() { currentCount = 0; }
public void Dispose() { }
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.