2017-10-15 53 views
1

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

而且我currenty停留在使用字典这一行: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); 
} 

Player类

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); 
    } 
} 

回答

4

由于您的变量p是一个KeyValuePair<int, Player>您无法访问到ConnectionId直接与p.ConnectionId。您应该使用p.Value.ConnectionId来访问它,因为在<int, Player> KeyValuePair中,Player对应于Value。您也可以访问similar fashion中的密钥。

1

KeyPairValue只包含两个属性键和值

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

你尝试用:的 p.Key代替p.ConnectionIdp.Value代替的p.PlayerPosition

编辑:我写了一个小lambda来只需使用Aggregate fct的代码即可。我传递默认值,然后为您的字典中的每个项目,它将concact另一个字符串。我也使用字符串插值来避免字符串连接($“{variable}”)。

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}|"); 
    } 
+0

另外我很确定你可以将你的foreach循环转换成一个不错的lambda表达式。我会给你更多的细节tmr – Seb

+0

看来你也错过了PlayPosition属性 – Seb

1

您在yr Player类中有ConnectionId,但是可以访问connectionId。 PS。奇怪为什么它编译。 顺便说一句,你可以使用players.Join - 一个LINQ扩展