从列表转换为字典,与foreach语句有关

时间:2017-10-15 04:07:33

标签: c# dictionary unity3d

我开始讨论将列表结构切换到字典而我遇到了一些麻烦。我正在修改我的foreach语句foreach (KeyValuePair <int, Player> p in players)以使用我的字典,但是我很难理解如何使用键值对访问我的播放器对象中的变量。

我目前使用字典坚持这一行:moveMsg += p.connectionId.ToString() + '%' + p.playerPosition.x.ToString() + '%' + p.playerPosition.y.ToString() + '|';

我得到的错误是:Assets/Scripts/Server.cs(118,18): error CS1061: Type System.Collections.Generic.KeyValuePair<int,Player>' does not contain a definition for connectionId' and no extension method connectionId' of type System.Collections.Generic.KeyValuePair<int,Player>' could be found. Are you missing an assembly reference?

如何进行修改?

声明字典:public Dictionary<int, Player> players = new Dictionary<int, Player>();

词典

// Ask player for their position

if (Time.time - lastMovementUpdate > movementUpdateRate)
{
    lastMovementUpdate = Time.time;
    string moveMsg = "ASKPOSITION|";
    foreach (KeyValuePair <int, Player> p in players)
        moveMsg += p.connectionId.ToString() + '%' + p.playerPosition.x.ToString() + '%' + p.playerPosition.y.ToString() + '|';
    moveMsg = moveMsg.Trim('|');
    Send(moveMsg, unreliableChannel, players);
}

玩家类

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

public class Player
{
    public string PlayerName;
    public GameObject Avatar;
    public int ConnectionId;
    public byte[] Tex;          // data coming from CanvasController
    public string Type;         // data coming from CanvasController
    public string Id;           // data coming from GameManager
    public int Strength;        // data coming from PlayerController
    public int Hitpoints;       // data coming from PlayerController
    public bool IsAlive;        // data coming from PlayerController

    // Initial method takes base arguments for testing
    public Player(string playerName, GameObject avatar, int connectionID)
    {
        PlayerName = playerName;
        Avatar = avatar;
        ConnectionId = connectionID;
    }
    // Overload method takes all animal arguments
    public Player(string playerName, GameObject avatar, int connectionID, byte[] tex, string type, string id, int strength, int hitpoints, bool isAlive)
    {
        PlayerName = playerName;
        Avatar = avatar;
        ConnectionId = connectionID;

        Tex = tex;
        Type = type;
        Id = id;
        Strength = strength;
        Hitpoints = hitpoints;
        IsAlive = isAlive;

        Debug.Log(id + " : " + type + " created with strength " + strength + ", hit points " + hitpoints + ", and a texture the size of " + tex.Length);
    }
}

3 个答案:

答案 0 :(得分:4)

由于您的变量pKeyValuePair<int, Player>,因此您无法直接使用ConnectionId访问p.ConnectionId。您应该使用p.Value.ConnectionId访问它,因为在<int, Player> KeyValuePair中,Player对应于Value。您还可以访问similar fashion中的密钥。

答案 1 :(得分:1)

KeyPairValue仅包含两个属性Key和Value

https://msdn.microsoft.com/en-us/library/5tbh8a42(v=vs.110).aspx

您尝试过: p.Key而不是p.ConnectionIdp.Value代替p.PlayerPosition

编辑:我使用Aggregate fct编写了一个小lambda来简单地编写代码。我传递了默认值,然后对于你的dict中的每个项目,它将统一另一个字符串。我还使用字符串插值来避免字符串连接($&#34; {variable}&#34;)。

    class Player
    {
        public Point Position { get; set; }
    }

    public void Test()
    {
        var players = new Dictionary<int, Player>();
        var msg = players.Aggregate(
              string.Empty, 
             (current, p) => current + 
                       $"{p.Key}%{p.Value.Position.X}%{p.Value.Position.Y}|");
    }

答案 2 :(得分:1)

您在玩家类中有一个ConnectionId,但访问connectionId。 PS。奇怪的是为什么编译。 顺便说一下,你可以使用player.Join - 一个linq扩展