循环遍历列表元组,如果没有匹配则添加

时间:2015-03-08 20:42:24

标签: c# list loops tuples

我正在用C#编写游戏服务器,每当有人用他的用户名发送登录消息时,我将他添加到ID为IDENDPOINT,USERNAME的元组列表中。 我想检查客户端是否与已连接的客户端具有相同的用户名,因此我尝试遍历列表并获取list.Item3'这是用户名'并使用String.Equals(list.Item3,username)检查用户名是否存在。 我的问题是当我循环时,我的代码只比较列表中的第一个元组,如果是真的则发送错误消息,如果没有则发送接受消息,当列表有+1客户端时它只比较第一个也是即使元组号2或3 ...具有该用户名,也接受。 我尝试了很多方法,这是我试过的最后一个代码:

for (int i = 0; i < clientsInfoList.Count; i++)
{
    bool isUsed;
    if (String.Equals(clientsInfoList[i].Item3, Username))
    {
        isUsed = true;
    }

    if (isUsed)
    {
        Console.WriteLine("Username is already used!");
        udpServer.Send(Encoding.ASCII.GetBytes("REFUSED"), Encoding.ASCII.GetByteCount("REFUSED"), remoteEP);
        break;
    }            
    else if(!isUsed)
    {
        clientsInfoList.Add(new Tuple<int, IPEndPoint, string>(id, remoteEP, Username));
        Console.WriteLine("Username has been added to the list :)");
        udpServer.Send(Encoding.ASCII.GetBytes("ACCEPTED"), Encoding.ASCII.GetByteCount("ACCEPTED"), remoteEP);                    
    }
}

我尝试了许多其他方法,但我无法实现验证。 提前谢谢。

4 个答案:

答案 0 :(得分:1)

你把所有东西放在一个循环中。为什么?您应该仅使用循环来检查是否使用了用户名,并将消息发送到其外部。

首先,你想强制你的循环只在它应该的时候工作。您可以通过在它之前声明isUsed并将其添加到条件中来实现。然后,在循环中,您只检查是否采用名称并更改变量的值。循环将遍历所有客户端,或者在遇到符合条件的第一个名称时结束。循环结束后,您应根据结果决定发送哪个命令。

bool isUsed = false;
for (int i = 0; i < clientsInfoList.Count && !isUsed; i++)
{
   isUsed = String.Equals(clientsInfoList[i].Item3, Username);
}

if (isUsed)
{
   Console.WriteLine("Username is already used!");
   udpServer.Send(Encoding.ASCII.GetBytes("REFUSED"), Encoding.ASCII.GetByteCount("REFUSED"), remoteEP);
}
else
{
   clientsInfoList.Add(new Tuple<int, IPEndPoint, string>(id, remoteEP, Username));
   Console.WriteLine("Username has been added to the list :)");
   udpServer.Send(Encoding.ASCII.GetBytes("ACCEPTED"), Encoding.ASCII.GetByteCount("ACCEPTED"), remoteEP);

}

答案 1 :(得分:1)

你可以做到

var isUsed = clientsInfoList.Any(info => info.Item3 == Username);
if (isUsed)
{
  // ...
}
else
{
  // ...
}

我假设Item3T3的{​​{1}})和Tuple<T1, T2, T3>都有编译时类型Username。< / p>

答案 2 :(得分:0)

为什么要将整个逻辑放在for循环中?只将下面的代码放在for循环中。

            bool isUsed;
            if (String.Equals(clientsInfoList[i].Item3, Username))
            {
                isUsed = true;
            }

现在它将验证元组中的所有元素并执行剩余的逻辑。

答案 3 :(得分:0)

你完全以错误的方式解决这个问题,如果我是你,我会做的第一件事就是摆脱元组,创建一个包含你需要的3个属性的类。

同样在这种情况下尝试使用HashSet而不是列表,它们会更好地进行优化,如果您拥有大量客户端,它们将帮助您的游戏更快地运行。

实现您所要求的最简洁的方法是使用LINQ,以下是我将如何重写您上面编写的代码。

public class Game 
{
    public Game()
    {
        this.Clients = new HashSet<Clients>(); 
    }

    public HashSet<Client> Clients { get; set;}

    public void OnClientConnect(Client newClient)
    {
        // Are there any clients with the username that the newUser is attempting to use?
        bool usernameIsFree = this.Clients.Any(clients => clients.UserName == newClient.UserName);

        if (usernameIsFree)
        {
            this.Clients.Add(newClient);
            Console.WriteLine("Username has been added to the list :)");
            // UDP stuff here...
            return;
        }

        Console.WriteLine("Username is already used!");
        // UDP stuff here   
    }
}
public class Client 
{
    public int ClientId { get; set; }
    public IPEndPoint IPEndPoint { get; set; }
    public string UserName { get; set; }
}