可变范围问题C#

时间:2013-09-17 23:51:58

标签: c# variables static scope

我正在学习C#,我在简单的控制台程序中遇到了变量范围问题。

到目前为止,该程序运行良好,但我知道在尝试引用先前实例化的变量时会遇到问题。

我尝试将方法从静态更改为非静态,并且还应用了公共/私有访问但无济于事。

我只需要朝着正确的方向轻推,希望有人可以提供帮助!

我得到的错误信息是:

  

错误1非静态字段,方法或属性'ConsoleApplication2.Program.game()'

需要对象引用
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication2
{
    public class Program
    {
        int numberToGuess;
        int numberGuessed;
        int triesRemaining;

        public void game()
        {
            Console.WriteLine("           ==Welcome to Guess My Number== \n");
            Console.WriteLine("Player 1: Please enter your number to guess between 1 and 20: \n");
            numberToGuess = int.Parse(Console.ReadLine());
            Console.WriteLine("Player 2, please enter your first guess, you have 7 tries: \n");
            numberGuessed = int.Parse(Console.ReadLine());

            if (numberGuessed == numberToGuess)
            {
                correct();
            }
            else
            {
                incorrect();
            }

        }

        public void correct()
        {
            Console.WriteLine("Congratulations, the number was in fact " + numberToGuess);
        }

        public void incorrect()
        {

        }


        static void  Main(string[] args)
        {
            game();            
        }
    }
}

3 个答案:

答案 0 :(得分:4)

实例成员(未标记static关键字的成员)每个对象实例存在一次。 对象的每个实例都会获得自己的副本。

另一方面,

static 成员对整个类存在一次,并由所有对象实例共享。

所以,如果你有一个班级:

class Foo
{
   public static int Alpha { get ; set ; }
   public        int Bravo { get ; set ; }
}

无论您创建了Foo个类的实例数,都只有Alpha个实例。任何实例方法或属性都可以直接访问静态成员。

实例成员,因为它们存在于每实例基础上,需要一个对象实例来引用它们。如果您向Foo类添加一些方法:

public static int DoSomething()
{
   return Alpha * 3 ;
}

完全有效 - 方法是静态的,成员是静态的。同上一个实例方法:

public int DoSomethingElse()
{
  return Alpha * 3 ;
}

这样的事情会失败:

public static int AndNowForSomethingCompletelyDifferent()
{
  return Alpha * 3 + Bravo ;
}
如果没有引用Bravo的实例,则无法在此引用

Foo。然而,这将有效:

public static int AndNowForSomethingCompletelyDifferent( Foo instance )
{
  return Alpha * 3 + instance.Bravo ;
}

就像这样:

public int AndNowForSomethingCompletelyDifferent()
{
  return Alpha * 3 + Bravo ;
}

由于该方法是非静态的(实例方法),因此它的this实例具有隐式引用(Foo)。以上完全等同于

public int AndNowForSomethingCompletelyDifferent()
{
  return Alpha * 3 + this.Bravo ;
}

在您的情况下,您可以在Program方法中实例化课程Main()

public static void Main( string[] args )
{
  Program p = new Program() ;
  p.game() ;
  return ;
}

或者您可以将方法game()correct()incorrect()标记为static,就像标记Main()方法一样。

希望这有帮助!

答案 1 :(得分:0)

static个方法/字段属于用户定义的类型,而不属于实例。

例如,如果你看一下这段代码:

public class MyClass
{
    public static void Foo()
    {
    }
}

Foo()方法不会从MyClass的实例访问。由于它是static,因此您可以从用户定义的类型本身访问它。例如:

public class Program
{
    static void Main(String[] args)
    {
        MyClass.Foo();
    }
}

由于Main()static,因此您只能在其中引用静态方法或变量(这不包括从本地实例变量引用的方法)。

在您的代码中,方法game()和游戏调用/调用的字段/方法不是static,因此您只能通过对象实例访问它。当然,制作game()和所有其他字段/方法static会产生一段代码。

有关static类型的详细信息,请查看此处:http://msdn.microsoft.com/en-us/library/98f28cdx.aspx

答案 2 :(得分:0)

我已经完成了这些方法并且看起来效果很好!

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

 namespace ConsoleApplication2
{
public class Program
{
    int numberToGuess;
    int numberGuessed;
    int triesRemaining = 7;
    string playAgain;
    string player1, player2;

    public void game()                                                                                                              //Initiates the game instance
        {
            Console.WriteLine("           ==Welcome to Guess My Number== \n");
            Console.WriteLine(" Player 1, Please enter your name: \n");
            player1 = Console.ReadLine();
            Console.Clear();
            Console.WriteLine("                      ==Guess My Number== \n");
            Console.WriteLine("Hello " + player1 + " : Please enter your number to guess between 1 and 20: \n");
            numberToGuess = int.Parse(Console.ReadLine());
            Console.Clear();
            Console.WriteLine("           ==Guess My Number== \n");
            Console.WriteLine(" Player 2, Please enter your name: \n");
            player2 = Console.ReadLine();
            Console.Clear();
            Console.WriteLine("Hello " + player2 + " please enter your first guess, you have 7 tries: \n");
            numberGuessed = int.Parse(Console.ReadLine());

            if (numberGuessed == numberToGuess)
            {
                Console.WriteLine("Congratulations, the number was in fact " + numberToGuess);
                newGame();
            }
            else
            {
                incorrect();
            }

        }

    public void incorrect()                                                                                                         //Method for dealing with incorrect answers
    {
        for (int x = 0; x < 6; x++)
        {
            triesRemaining--;
            Console.WriteLine("Incorrect, you have " + triesRemaining + " tries remaining \n");
            Console.WriteLine(player2 + ", please enter your next guess: \n");
            numberGuessed = int.Parse(Console.ReadLine());

            if (numberGuessed == numberToGuess)
            {
                Console.WriteLine("Congratulations, the number was in fact " + numberToGuess);
                newGame();
            }
            else { 
                //Do nothing
            }

        }

        Console.WriteLine("You have used up all your tries! You have failed. The number was: " +numberToGuess + "\n");
        newGame();
    }                                                      //Method for dealing with incorrect answers

    public void newGame()                                                                                                           //Method that gives the user the option to start a new game instance
    {
        Console.WriteLine("Would you like to play again? Type yes or no: \n");
        playAgain = Console.ReadLine();
        playAgain = playAgain.ToLower();
        if (playAgain == "yes")
        {
            Console.Clear();
            game();
        }
        else if (playAgain == "y")
        {
            game();
        }
        else
        {
            //Do nothing
        }
    }                                                        

   static void  Main(string[] args)
    {
        new Program().game();

    }
}
}