【问题标题】:how to pass values from foreach loop to another method如何将值从 foreach 循环传递到另一个方法
【发布时间】:2012-11-22 13:35:54
【问题描述】:

我需要做的是从一个名为 private void ReceiveData() 的方法中获取 foreach 值并将它们发送到另一个方法 void Update() 。如何在 C# 中做到这一点?

private void ReceiveData() 
    {

       IPEndPoint remoteIP = new IPEndPoint(IPAddress.Parse("10.0.2.217"), port);
       client = new UdpClient(remoteIP);
        while (true) 
        {
           try 
            {
                IPEndPoint anyIP = new IPEndPoint(IPAddress.Any, 0);
                data = client.Receive(ref anyIP);

                int nIndex = 0;
                foreach(SignalIndex si in xmlreader.cdpSignals)
                {
                     x= ReadSingleBigEndian(data, si.index + 0);
                     y= ReadSingleBigEndian(data, si.index + 4);
                     z= ReadSingleBigEndian(data, si.index + 8);
                     alpha= ReadSingleBigEndian(data, si.index + 12);
                     theta= ReadSingleBigEndian(data, si.index + 16);
                     phi= ReadSingleBigEndian(data, si.index + 20);

                //  xmlreader.unityGameObjects[nIndex].transform.localPosition = new Vector3(x,y,z);
                //  xmlreader.unityGameObjects[nIndex].transform.Rotate(alpha,theta,phi);   
                }

            }
            catch (Exception err) 
            {
               print(err.ToString());
            }

        }

        client.Close();
    }


    void Update() 
    {
        foreach(GameObject go in xmlreader.unityGameObjects)
        {
            go.transform.localPosition = new Vector3(x,y,z);
            go.transform.transform.Rotate(alpha,theta,phi);
        }
    }

有 2 种方法,我需要从 ReceiveData() 获取 foreach 中的值并在方法 Update() 中实例化它们。 ReceiveData() 中 foreach 中的所有变量都是公开的,但在 Update() 中它们都取 0。

【问题讨论】:

  • “从一种方法获取 foreach 值”是什么意思?
  • 需要更多上下文。不清楚你的意思,特别是因为这两种方法都没有参数并返回void
  • @MarcGravell,嗨!我用更多的上下文更新了我的问题:)

标签: c# methods foreach unity3d


【解决方案1】:

编辑 2:

ReaderWriterLockSlim 的文档:http://msdn.microsoft.com/en-us/library/system.threading.readerwriterlockslim.aspx

struct CoordData
{
    public float X, Y, Z, Alpha, Theta, Phi;
    public int NIndex;
}

private List<CoordData> coordDataList = new List<CoordData>();
private ReaderWriterLockSlim lockObj = new ReaderWriterLockSlim();

private void ReceiveData() 
{

   IPEndPoint remoteIP = new IPEndPoint(IPAddress.Parse("10.0.2.217"), port);
   client = new UdpClient(remoteIP);
    while (true) 
    {
       try 
        {
            IPEndPoint anyIP = new IPEndPoint(IPAddress.Any, 0);
            data = client.Receive(ref anyIP);

            int nIndex = 0;
            foreach(SignalIndex si in xmlreader.cdpSignals)
            {
                 x= ReadSingleBigEndian(data, si.index + 0);
                 y= ReadSingleBigEndian(data, si.index + 4);
                 z= ReadSingleBigEndian(data, si.index + 8);
                 alpha= ReadSingleBigEndian(data, si.index + 12);
                 theta= ReadSingleBigEndian(data, si.index + 16);
                 phi= ReadSingleBigEndian(data, si.index + 20);

                 lockObj.EnterWriteLock();
                 try
                 {
                     coordDataList.Add(new CoordData() { X = x, Y = y, Z = z, Alpha = alpha, Theta = theta, Phi = phi, NIndex = nIndex });
                 }
                 finally
                 {
                     lockObj.ExitWriteLock();
                 }

                 nIndex++; //I'm assuming you want to do this here otherwise you'll be changing the same object in the array every time  
            }

        }
        catch (Exception err) 
        {
           print(err.ToString());
        }

    }

    client.Close();
}

void Update()
{
    lockObj.EnterReadLock();
    try
    {
        foreach (CoordData data in coordDataList)
        {
            xmlReader.unityGameObjects[data.NIndex].localPosition = new Vector3(data.X,data.Y,data.Z);
            xmlReader.unityGameObjects[data.NIndex].Rotate(data.Alpha,data.Theta,data.Phi);
        }
    }
    finally
    {
        lockObj.ExitReadLock();
    }
}

【讨论】:

  • 我已经编辑了我的答案,但我怀疑它是否会起作用,因为我刚刚在下面的答案中看到了 cmets。您是否需要在收到数据后立即调用 Update()?或者您可以将值存储在数组或其他东西中,然后在 Update() 中读取它们吗?
  • 当我在另一个脚本中调用 Update() 时,我的 Update() 无法接受任何参数我收到一个错误,提示我需要从主线程调用它,但我不知道如何传递x,y,z,alpha,theta,phi 到 Update()
  • 很抱歉,我遇到了一个错误:错误 CS1914:静态字段或属性 UDPReceive.CoordData.NIndex' cannot be assigned in an object initializer; error CS0122: UDPReceive.CoordData.NIndex' 由于其保护级别而无法访问
  • 你有机会尝试这个吗?
  • 非常感谢它有效!但是还有一个问题,在运行时打印出以下“System.Threading.LockRecursionException:在 中的 System.Threading.ReaderWriterLockSlim.TryEnterWriteLock (Int32 millisecondsTimeout) [0x00000] 中持有读锁时无法获取写锁:0 在 System.Threading.ReaderWriterLockSlim.EnterWriteLock () [0x00000] in :0 " 有没有办法解决它?
【解决方案2】:

foreach 的工作方式如下:

在您的方法 (ReceiveData) 中,您将循环使用某种方法。然后从那个循环中你可以调用另一个方法(Update)。但是,您将不得不传递这些变量。您的方法目前是无效的,并且没有任何参数。

我建议如下:

private void ReceiveData()
{
    var data = GetMyDataFromSomewhere(); // data should be an IEnumerable of some sort

    foreach (MyDataItemType dataItem in data)
    {
        Update(dataItem);
    }
}

private void UpdateData(MyDataItemType dataItem)
{
    // Do some update to dataItem here...
}

在您使用更多代码进行新更新后,还有更多信息可供使用。显然,您正在类中设置一些字段/属性(xyz 等)。而 update 方法将使用这些来更新一些东西。

那为什么不直接在foreach 循环中调用Update(),或者在循环之后调用,如果它只需要在设置后完成:

foreach(SignalIndex si in xmlreader.cdpSignals)
{
    x= ReadSingleBigEndian(data, si.index + 0);
    y= ReadSingleBigEndian(data, si.index + 4);
    z= ReadSingleBigEndian(data, si.index + 8);
    alpha= ReadSingleBigEndian(data, si.index + 12);
    theta= ReadSingleBigEndian(data, si.index + 16);
    phi= ReadSingleBigEndian(data, si.index + 20);

    UpdateData(); // Just call it!
}

【讨论】:

  • 我的 void Update() 不能带任何参数 :(
  • 你可以创建参数吗?
  • 当我调用我的 Update() 时,它会显示一个错误:get_transform 只能从主线程调用。加载场景时,构造函数和字段初始化程序将从加载线程中执行。不要在构造函数或字段初始化程序中使用此函数,而是将初始化代码移至 Awake 或 Start 函数。
  • 在这种情况下,我们肯定需要更多的上下文。你在使用某种图书馆吗?这个类是否继承自某些东西?它到底给出了什么错误?例如,我什至没有在任何地方看到get_transform...请在您的问题中添加更多信息。
猜你喜欢
  • 1970-01-01
  • 2019-03-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-14
  • 1970-01-01
  • 2015-12-27
相关资源
最近更新 更多