繁体   English   中英

C#警告foreach中未使用的变量

[英]C# warning for unused variable in foreach

我有以下代码(简化):

IEnumerable MyFunc(...){
    IAsyncResult res = mSocket.BeginReceive(mReceptionArray, 0, pNbBytes, SocketFlags.None, null, null);
    while (!res.IsCompleted){
        yield return new WaitForFixedUpdate();
    }
}

可以这样使用:

foreach(object o in MyFunc());

当然,编译器会抱怨,因为从未使用过o 有什么办法解决吗?

编辑

foreach在协程中执行。 在从服务器接收数据之前,我需要阻止协程的执行。 我可以使用常规的Receive(),但这会阻止所有其他协程,而我不能这样做:还有许多其他协程正在运行,而使用Receive或EndReceive阻止此协程会阻止它们。

无论如何,这不是一个忙碌的等待。

重构代码的任何建议都值得欢迎,我对C#经验不足。

我将编写一个新的扩展方法以使用该序列并忽略结果。 例如:

// TODO: Documentation
public static void ConsumeSequence<T>(this IEnumerable<T> source)
{
    // TODO: Argument validation
    using (var iterator = source.GetEnumerator())
    {
        while (iterator.MoveNext())
        {
            // Deliberate no-op
        }
    }
}

然后,在调用代码中就可以清楚地知道自己在做什么,并且您只是在故意使用序列并忽略结果。

像sixlettervariables,它不是真正清楚,你的序列是恰当的,但如果你只想消耗序列,这就是我会做。

这是Javad_Amiry答案的一种变体(顺便说一下,我对此+1了):

public static void Unused<T>(this T value) { }

因为它是扩展方法,所以可以使用以下语法从任何地方调用它:

foreach (object o in MyFunc())
    o.Unused();

现在,以防万一,我确实尝试在其上方添加[Conditional("NEVER_COMPILE_ME")] ,但可悲的是,这会使警告再次出现。


顺便说一句,根据我在Unity中的经验, yield return null根本不会杀死协程。 但是您的代码实际上是一个繁忙的等待,因为您没有将协程交给Unity运行-您是在自己运行它。 使用您的代码,您构造的WaitForFixedUpdate对象将以o (或为null ),并且您将忽略它并再次运行。 Unity从未见过。 如果您希望Unity进行WaitForFixedUpdate或其他任何操作,则必须通过调用StartCoroutine(MyFunc())使其对协程进行控制。 这是MonoBehaviour的实例方法,只要MonoBehaviour保持启用状态,协程便会运行完成。 希望能澄清一下:)

编辑-我刚刚注意到您说“ foreach”本身在协程内部运行。 在这种情况下,您可以执行以下操作:

var subCoroutine = StartCoroutine(MyFunc());
yield return subCoroutine;

或等效的单行版本:

yield return StartCoroutine(MyFunc());

这将告诉Unity等待其他协程完成,然后再继续执行此协程。

或者,如果您需要一个较低的级别,可以这样做:

foreach (object o in MyFunc())
    yield return o;

看完你在做什么之后,我真的不觉得这就是你想要的。 您已经使用foreach语句实现了繁忙等待。 您已经说过这样做是为了不阻塞其他协程,但是我看不到忙等待循环也不会阻塞其他协程。

每个.Begin*都有一个对应的.End* ,它将优雅地暂停线程的执行,直到异步操作完成。

// Suspend execution until the receive operation completes
mSocket.EndReceive(res);
foreach(object o in MyFunc())
    doNothing(o); // avoiding warning

并创建一个空白方法:

void doNothing(object o){ }

您的代码看起来很奇怪-当您立即阻止直到完成之前,为什么还要在套接字上使用异步I / O方法呢?

这将取消您的警告:

#pragma warning disable 0168
// code goes here
#pragma warning restore 0168

但是在做这样的事情之前,请考虑一下是否有更好的方法。 参见乔恩的答案。

不是最有效的,但肯定是简短的:

MyFunc().Any(x => false);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM