0

更新:请参阅底部的EDIT 3 。

我是 C# 和一般编程的初学者(所以请温柔一点!)。我遵循了大量的教程并阅读了书籍,并认为我理解了课程。到现在。

我有一个相当简单的单类项目,它使用 2D 字符串数组来设置一个 10x10 的字母 E(空)和 F(全)网格。我使用 int x 和 int y 来引用数组的坐标,并使用 switch 来检测输入并从 x 和 y 中加减来确定数组单元格是空的还是满的。

class MainGame
{
public MainGame()
{
    string[,] mapTerr = new string[10, 10]
    {
        { "F", "F", "F", "F", "F", "F", "F", "F", "F", "F" },
        { "F", "E", "E", "E", "E", "E", "E", "E", "E", "F" },
        { "F", "E", "E", "E", "E", "E", "E", "E", "E", "F" },
        { "F", "E", "E", "E", "E", "E", "E", "E", "E", "F" },
        { "F", "E", "E", "E", "E", "E", "E", "E", "E", "F" },
        { "F", "E", "E", "E", "E", "E", "E", "E", "E", "F" },
        { "F", "E", "E", "E", "E", "E", "E", "E", "E", "F" },
        { "F", "E", "E", "E", "E", "E", "E", "E", "E", "F" },
        { "F", "E", "E", "E", "E", "E", "E", "E", "E", "F" },
        { "F", "F", "F", "F", "F", "F", "F", "F", "F", "F" },
    }; // long-winded I know, but helps visualise the array
    int x, y;
    string navDir;
    Console.WriteLine("Enter a command:");
    navDir = Console.ReadLine();
    switch (navDir)
    {
        case "N":
        case "n":
            x -= 1;
            if (mapTerr[x, y] == "F")
            {
                Console.WriteLine("You cannot move North, it is blocked!");
                x += 1;
            }
            else
            {
                Console.WriteLine("You move North.");
            }
            break;
        case "E":
        case "e":
            y += 1;
            if (mapTerr[x, y] == "F")
            {
                Console.WriteLine("You cannot move East, it is blocked!");
                y -= 1;
            }
            else
            {
                Console.WriteLine("You move East.");
            }
            break;
        // etc...

这工作正常。但是,我尝试将其拆分为单独的类:一个用于创建数组,另一个用于控制输入和输出。这是我的尝试:

class Program
{
    public static void Main(string[] args)
    {
        Map map = new Map();
        UserControl usercontrol = new UserControl();
    }
}

class Map
{
    string[,] mapTerr = new string[10, 10] {
    { // array contents here
    };
}

class UserControl
{
    int x, y;
    string navDir;

    public UserControl()
    {
        Console.WriteLine("Enter a command:");
        navDir = Console.ReadLine();
        switch (navDir)
        {
            case "N":
            case "n":
                x -= 1;
                if (mapTerr[x, y] == "F") // ERROR: The name 'mapTerr' does not exit in the current context"
                {
                    Console.WriteLine("You cannot move North, it is blocked!");
                    x += 1;
                }
                else
                {
                    Console.WriteLine("You move North.");
                }
                break;
            // etc...

我一生都无法弄清楚如何让它发挥作用。错误主要出现在从交换机内部调用数组时。

我意识到这是因为数组与 Map 类而不是 UserControl 类相关联,那么如何使其可见/可用?

尽管在这里和其他地方在线搜索了数组/范围/类部分,但没有什么能真正用简单的术语来完全解释事情。我认为这是范围问题,我试图以不可能的方式调用对事物的引用。如果有人能解释我做错了什么,也许能暗示我可以用正确的方式做事,我真的很感激!(为冗长的解释/问题道歉)

编辑 1:在该行旁边添加了特定的错误消息作为注释。这发生在开关中引用 mapTerr 的每一行上。

编辑 2:阐明实例化和类结构。

编辑 3:好的,字符串数组是在 Map 类中公开设置的,public string[,] elsaNav = new string[10, 10] {{/*contents*/};我在 Program 类中实例化了 map 类,但仍然无法从 UserControl 类中调用 mapTerr 数组,尽管使用map.mapTerr...

4

4 回答 4

2
public class Map
{
    public string[,] mapTerr = new string[10, 10] {
    { // array contents here
    };
}

public class UserControl
{
    int x, y;
    string navDir;
    Map myMap = new Map();

    public UserControl()
    {
        Console.WriteLine("Enter a command:");
        navDir = Console.ReadLine();
        switch (navDir)
        {
            case "N":
            case "n":
                x -= 1;
                if (myMap.mapTerr[x, y] == "F")
                {
                    Console.WriteLine("You cannot move North, it is blocked!");
                    x += 1;
                }
                else
                {
                    Console.WriteLine("You move North.");
                }
                break;
            // etc...
于 2012-11-22T10:29:15.470 回答
0

在使用本文中给出的建议进行编辑后,我不太确定您的最终解决方案如何,但我已经修复了代码,为您提供了一种使用它的方法,希望它可以帮助您查明错误你的代码:)

using System.Collections;
using System;

class Program
{
    public static void Main(string[] args)
    {
        UserControl usercontrol = new UserControl();
    }
}

class Map
{
// Private map
private string[,] mapTerr;

// Public map
public string[,] MapTerr
{
    get {return mapTerr;}
}

public Map(int width, int height)
{
    mapTerr = new string[width, height];

    for (int x = 0; x < width; x++)
    {
        for (int y = 0; y < height; y++)
        {
            mapTerr[x,y] = "E";
        }
    }
}
}

class UserControl
{
    int x, y;
    string navDir;
Map map;

    public UserControl()
    {
        map = new Map(10, 10);
        Console.WriteLine("Enter a command:");
        navDir = Console.ReadLine();
        switch (navDir)
        {
            case "N":
            case "n":
            x -= 1;
            if (map.MapTerr[x, y] == "F") // ERROR: The name 'mapTerr' does not exit in the current context"
            {
                Console.WriteLine("You cannot move North, it is blocked!");
                x += 1;
            }
            else
            {
                Console.WriteLine("You move North.");
            }
            break;
        // etc...
        }
}
}

如果缩进有点不对,我很抱歉,我很着急,现在无法访问适当的 C# 编译器,但上面的代码应该可以工作:)

顺便说一句,将您的地图和用户输入封装并分离到两个类中是个好主意!新程序员的良好开端:)

请记住在您的类中广泛使用属性来控制如何在您的类中访问数据成员。在大多数情况下,您不想让成员完全公开。相反,将它们设为私有并为它们创建一个属性,这样您就可以控制如何设置或访问数据。

当然,我刚刚快速编写了一些用字母初始化数组的示例逻辑,只是为了展示解决方案,因此您可能需要重新编写它以满足您自己的需要:)

此外,您希望如何使用地图对象还取决于您自己对客户端应如何使用代码的想法,我只是将 Map 对象作为 UserControl 类的组合,而不让客户端代码使用它。另一种方法当然是让客户端代码初始化自己的地图对象并将其传递给 UserInput 类的构造函数。

希望它可以帮助你。

[编辑]

好的,字符串数组在Map类中公开设置,public string[,] elsaNav = new string[10, 10] {{/ contents /}; 我在 Program 类中实例化了 map 类,但仍然无法从 UserControl 类中调用 mapTerr 数组,尽管使用了 map.mapTerr

好的,我还没有看到你的解决方案代码,但也许我仍然明白......让我试一试:P 基本上你是在 Program 类中实例化 Map 类,例如:

Map myMap = new Map();

然后您尝试直接在您的 UserControl 类的实例中访问“myMap”引用?在这种情况下,您不能简单地这样做。myMap引用仅在您从中调用它的 Program 类方法的范围内,因此当您尝试从UserControl类中引用它时,它不会对此有任何了解,它超出了它的范围。相反,您必须将引用传递给UserControl类,如下所示:

Map myMap = new Map();

UserControl newControl = new UserControl(myMap);

然后在类中,您的构造函数将如下所示:

    public UserControl(Map map)
    {
        map.MapTerr... etc
    }

也许我误解了你所说的,但如果这就是你的意思,那么上面的解决方案应该可以解决它:)

于 2012-11-22T20:29:22.480 回答
0

您还没有实例化地图类。

从公共 UserControl() 中,您需要沿 Map map = new Map();

然后通过 map.mapTerr[x, y] 访问 mapTerr

例如,请查看 Dejo 上面的回复。

于 2012-11-22T10:28:29.753 回答
-1

您的主要问题是 mapTerr 的默认保护级别是 Map 私有的。其次,即使它是公开的,你仍然需要进一步限定它,要么通过 Map 的实例化实例,要么将其设为静态:

static class Map
{
    public static readonly string[,] mapTerr = new string[10,10 {...}
}

要引用您需要完全限定该属性:

class UserControl
{
    public UserControl()
    {
        ...
        if (Map.mapTerr[x,y] == "F")
        { 
            ...
        }
    }
}

您还应该考虑 1) 将公共字段隐藏在属性后面,以及 2) 将字符串更改为字符。

于 2012-11-22T10:41:01.843 回答