将用户输入的字符串转换为c#中的对象

时间:2018-05-06 03:42:45

标签: c# type-conversion

我有一个类似终端游戏的战舰,用户输入一个像e2这样的坐标,程序检查我的对象Box的一个实例变量,它检查hasShip是否为真,如果是真,那么它将使坐标为e2 false,并输出“Ship destroyed”

问题在于我的所有对象都被称为a1,a2,a3,a4,a5,b1,b2等。

我创建了25个Box类的实例。所有的名字都是这样的。

一旦程序输入,e4,e5等我想将该字符串转换为对象。

例如(我想做这样的事情)

target = Console.ReadLine();
target.hasShip == true; 

我想将target转换为对象,然后使用target来使用Box类的方法。

因为另一种方法要求我加载if语句,这不是干净的代码,看起来不太好,如果你问我就是一种浪费。

提前致谢,

1 个答案:

答案 0 :(得分:2)

新答案:使用数组

我很慢。我没注意你正在制作类似战舰的游戏,而且我们知道"盒子"做一个矩形。我们可以将它有效地存储在一个数组中。

为什么我之前没有赶上这个事实?我想我需要正确醒来。

所以,使用数组:

var board = new Box[5, 5];

现在,为了填充它,我们可以做一个双循环:

for(var indexRow = 0; indexRow < 5; indexRow++)
{
    for(var indexCol = 0; indexCol < 5; indexCol++)
    {
        board[indexRow, indexCol] = new Box();
    }
}

注意:注意索引从0到4.总共5个值:{0,1,2,3,5}。

要从中查询,我们需要索引......

填充数组的附录

在评论中,OP表示每个Box都有一个id,随机选择船位。

我们可以在循环中给出id:

for(var indexRow = 0; indexRow < 5; indexRow++)
{
    for(var indexCol = 0; indexCol < 5; indexCol++)
    {
        var box = new Box();
        box.vhID = (((char)(((int)'a') + indexRow))).ToString() + ((char)(((int)'1') + indexCol)).ToString();
        board[indexRow, indexCol] = box;

    }
}

我在这里做的是从索引构造id。基本上取'a'的值并添加indexRow会在'a'indexRow时为0'b'1 }} 等等。同样,我们得到代表该列的数字。

注意:我们将char转换为int,进行添加,然后转换回char ...然后从{{1}转换回来到char。一旦我们有了字符串,我们就可以将它们连接起来。

我认为我们不需要这个ID。但是,嘿,你可以这样做。

OP还提到他将随机挑选4个船位。足够公平:

string

由于用户输入了一个字符串,我建议创建一个函数将其转换为索引对:

var random = new Random();
for (var ships = 0; ships < 4; ships++)
{
    board[random.Next(0, 4), random.Next(0, 4)].hasShip = true;
}

首先验证 var input = Console.ReadLine(); if (TryGetCoordinates(input, out int irow, out int icol)) { var target = board[irow, icol]; } else { Console.WriteLine("The cell {0} does not exist.", input); } // ... bool TryGetCoordinates(string cell, out int indexRow, out int indexCol) { // ... }

null

注意:您可以随意使用 bool TryGetCoordinates(string cell, out int indexRow, out int indexCol) { indexRow = -1; indexCol = -1; if (cell == null) { return false; } // ... } TrimToUpper

我们知道必须是一个字母后跟一个数字,我们可以验证长度:

ToUpperInvariant

我们提取字符并从中提取坐标。注意到第一个是字母,另一个是数字。我们还可以验证它们是否有限。

 bool TryGetCoordinates(string cell, out int indexRow, out int indexCol)
 {
     indexRow = -1;
     indexCol = -1;
     if (cell == null)
     {
         return false;
     }
     if (cell.Length != 2)
     {
         return false;
     }
     // ...
 }

当然,你可以进行类似于旧答案中解释的验证循环。

注意:我在旧答案中描述的值类型问题仍然适用于数组。

旧答案:使用词典

我相信您不希望将 bool TryGetCoordinates(string cell, out int indexRow, out int indexCol) { indexRow = -1; indexCol = -1; if (cell == null) { return false; } if (cell.Length != 2) { return false; } indexRow = (int)cell[0] - (int)'a'; indexCol = (int)cell[1] - (int)'1'; return indexRow < 5 && indexRow >= 0 && indexCol < 5 && indexCol >= 0; } 转换为对象(顺便说一下,string是一个对象),您想要选择之前创建的string对象在Box上。而且你想在不使用if语句的情况下完成它。你需要的是一本字典。

所以,你会string意味着它是一个字典,你可以按字符串查询并存储Dictionary<string, Box>

<强>补遗

  • 在这种情况下,string是键类型,我们将通过它来访问字典。当我们向字典添加一个对象时,我们用一个键来识别它,当我们检索它时,我们也使用该键。密钥不必是Box,您可以选择其他类型。在这种情况下,string很方便,因为它是您从string获得的。
  • 您可以创建字典来存储您需要的任何类型。如果您不需要Console.ReadLine(),则可以创建一个存储其他内容的字典。

创建和填充词典

然后,您将所有Box对象添加到Dictionary中,如下所示:

Box

其中var dict = new Dictionary<string, Box>(); // ... dict.Add("a1", CreateBoxA1()); 表示您必须创建对象的任何方式。不,您不需要为每个CreateBoxA1创建一个方法......您可以这样做:

Box

或者其他什么。我不知道你是如何创建它们的,所以考虑一个占位符,好吗?确定。

从词典中查询和检索值

在您的词典中拥有所有dict.Add("a1", new Box()); 个实例后,您可以使用Box获得所需的实例:

string

附录:您从Console.WriteLine("Enter the name of the Box:"); var name = Console.ReadLine(); var target = dict[name]; 获得的值是您使用该键添加到词典中的值。因此,如果用户输入dict[name],则"a1"将是我们使用dict[name]"a1")添加的值。同样,如果您需要的不是dict.Add("a1", new Box());,您可以创建一个字典来存储不同的类型。

输入验证

您还可以使用词典来验证Box是否对应于存在的Box,例如:

string

毋庸置疑,但是......你可以根据它做出一个循环,例如:

Console.WriteLine("Enter the name of the Box:");
var name = Console.ReadLine();
if (dict.KeyExists(name))
{
    var target = dict[name];
    // ...
}
else
{
    Console.WriteLine("The Box {0} does not exist", name);
}

此外,不言而喻,但是......您可以添加自己的验证和卫生步骤。例如,使用ToUpperToUpperInvariantTrim。我想提醒一下,将Box target = null; while(true) { Console.WriteLine("Enter the name of the Box:"); var name = Console.ReadLine(); if (dict.KeyExists(name)) { target = dict[name]; break; } Console.WriteLine("The Box {0} does not exist", name); } 更改为大写或小写是文化敏感的。

另请参阅:Best Practices for Using Strings in .NET

编辑字典中的删除对象

获得从词典中检索的对象...

string

我们可以使用它,甚至可以修改它:

 var target = dict[name];

如果 var target = dict[name]; if (target.hasShip) // no need for "== true" if hasShip bool { target.hasShip = false; Console.WriteLine("Ship Destroyed"); } 是值类型,则必须特别注意。对于自定义类型,表示它不是Box而是class。值类型的问题在于它们在赋值时被复制,这意味着当您使用值类型执行struct时,您将获得一个副本。然后,您必须在操作字典后更新字典:

var target = dict[name];

注意:正如我上面所说,这仅适用于值类型。

如果必要,您甚至可以从字典中删除 var target = dict[name]; if (target.hasShip) // no need for "== true" if hasShip bool { target.hasShip = false; dict[name] = target; Console.WriteLine("Ship Destroyed"); }

Box