【问题标题】:Why is my bool property is not receiving a value using Get/Set in C#?为什么我的 bool 属性没有在 C# 中使用 Get/Set 接收值?
【发布时间】:2014-07-18 15:07:29
【问题描述】:

由于某种原因,我似乎无法使用 Get/Set 从类 manageWords 中更改类 checkSpell 中属性 NoMoreWords 的值。

完整的代码在下面,但重要的一点在这里。

checkSpell 中有一个名为 NoMoreWords 的 bool 属性。 然后我在manageWords 中创建checkSpell 对象的实例并将NoMoreWords 属性更改为true。我的监视窗口证明manageWords 中的值已更改,但一旦我回到checkSpellNoMoreWords 仍然为假。

您能发现问题并指出正确的方向吗?谢谢。

这是checkSpell

class checkSpell
{

    public bool finished = false;

    public bool NoMoreWords { get; set; }

    public void getWord()
    {

        manageWords mngit = new manageWords();
        speakIt spk = new speakIt();

        do
        {

            string word = mngit.readFile();     // Open the file and gets the word

            if (NoMoreWords == true)
            {
                Console.WriteLine("NoMoreWords is TRUE");
                break;
            }

            //if (word == string.Empty) break;


            Console.WriteLine();

            Console.WriteLine("Write the word: {0}", word.ToUpper());
            //spk.sayThis("Write the word: " + word);
            Console.Write(">");

            char[] a = word.ToCharArray(); //Converts string into chars

            getLetter(a); // METHOD



          //  if (finished == true) break;               

            System.Threading.Thread.Sleep(30);

            //spk.sayThis("Correct!");

            Console.WriteLine("");

        } while (!finished);

        Console.WriteLine("XXXX Bye Bye");
        spk.sayThis("Bye Bye");

    }


    /************************************************************************************************************************
     * Goes through the word (as a char[]) and compare with the typed letters                                               *
     ************************************************************************************************************************/

    public void getLetter(char[] a)
    {

        int b = 0;
        ConsoleKeyInfo k;
        ConsoleColor orig = Console.ForegroundColor;
        int CL = Console.CursorLeft;
        int CT = Console.CursorTop;
        string capOut = "";

        for (int i = b; i < a.Length; i = +b)
        {
            k = Console.ReadKey(true);

            if (k.Key == ConsoleKey.Escape)
            {
                finished = true;
                break;
            }

            if (k.KeyChar == a[i])
            {
                Console.ForegroundColor = orig;
                capOut = k.KeyChar.ToString().ToUpper();

                Console.Write(k.KeyChar.ToString().ToUpper());
                b++;
                CL = Console.CursorLeft; //Get the cursor position of the last correct letter 
                CT = Console.CursorTop;

            }
            else if (k.Key == ConsoleKey.Backspace)
            {

                if (Console.CursorLeft > CL) Console.SetCursorPosition(Console.CursorLeft - 1, CT);
                ConsoleColor bg = Console.BackgroundColor;
                Console.ForegroundColor = bg;
                Console.Write(" ");
                Console.CursorLeft = Console.CursorLeft - 1;

            }
            else if (k.Key == ConsoleKey.Enter)
            {
                // i don't want to change line
            }

            else
            {

                Console.ForegroundColor = ConsoleColor.Red;
                Console.Write(k.KeyChar.ToString().ToUpper());
                Console.ForegroundColor = orig;

            }

        }

    }

现在manageWords

 class manageWords // Check file, open and edit it
{

    public int lineNumber;

    //Check if file exists
    public string readFile()
    {

        string CurrentLine = "";
        int count = 0;

        checkSpell ckt = new checkSpell();

        try
        {


            START:

            count = File.ReadLines(Path.Combine(Environment.CurrentDirectory, "words.txt")).Count(); // Gets number of lines

            var lines = File.ReadLines(Path.Combine(Environment.CurrentDirectory, "words.txt"));

            if (lineNumber < count)
            {
                CurrentLine = lines.Skip(lineNumber).First();
                lineNumber++;
            }
            else 
            {
                ckt.NoMoreWords = true;
                Console.WriteLine("");
                Console.WriteLine("Do you want to play it again? Yes/No: ");
                if (Console.ReadLine() == "yes")
                {
                    lineNumber = 0;
                    goto START;

                }
                else ckt.NoMoreWords = true;
            } 

        }
        catch (Exception e)
        {
            // Let the user know what went wrong.
            Console.WriteLine("The file could not be read:");
            Console.WriteLine(e.Message);
            // Console.ReadLine();
        }

        return CurrentLine;
    }

}

【问题讨论】:

  • 您能否提供一个较小的最小重现问题,其中不包含与重现您的问题无关的大量代码?
  • 你是什么意思“一旦我回到 checkSpell...” - 你在 checkSpell 的实例中和刚刚设置的实例相同吗?
  • @Servy 因为我不知道是什么导致了问题,所以我认为从代码中删除任何内容实际上可以消除可能的原因。但如果我问另一个问题,我会记住这一点。
  • @Tim 我在使用 Step Into 进行调试并观察属性值时是认真的。
  • @user3853326 这就是为什么您需要在删除多余的代码后实际运行程序,以确保它确实复制了问题,而不仅仅是猜测。实验。删除代码,运行程序,看看会发生什么。

标签: c# properties get set


【解决方案1】:

这里的原因是您有两个 checkSpell 实例在运行。

  • checkSpell 的getWord 方法是一个实例方法,因此它可以访问那个 实例的NoMoreWords 属性
  • getWord 构造一个manageWords 类型的新对象并调用readFile
  • manageWords.readFile 构造另一个 checkSpell 实例,而 this 实例将 NoMoreWords 变为 true

原始实例,即您在其上调用 getWord 的实例,没有改变。

也许您应该将原始实例传递给readFile 方法,而不是让该方法构造一个新的checkSpell 对象实例?

基本上改变你的 readFile 方法如下:

public string readFile(checkSpell ckt)

然后在调用readFile时传入checkSpell实例:

string word = mngit.readFile(this);

还记得删除readFile 中构造新checkSpell 实例的行,无论如何你都必须这样做,因为你不能同时拥有ckt 参数一个局部变量。

【讨论】:

    【解决方案2】:

    因为 manageWords.readFile 在自己的本地 checkSpell 对象 (ckt) 中创建,所以对该本地对象的任何更改都不会影响调用 manageWords.readFile 的 checkSpell 对象。您应该将调用者传递给 manageWords.readFile,例如,

    public void getWord()
    {
        manageWords mngit = new manageWords();
        speakIt spk = new speakIt();
    
        do
        {
            string word = mngit.readFile(this);     // pass local checkSpell
            // etc
    
    class manageWords // Check file, open and edit it
    {
        public int lineNumber;
    
        //Check if file exists
        public string readFile(checkSpell ckt)
        {
            string CurrentLine = "";
            int count = 0;
            // etc
    

    您还可以将 checkSpell 对象传递给 manageWords 构造函数并存储在 manageWords 的字段中:

    public void getWord()
    {
        manageWords mngit = new manageWords(this);     // pass local checkSpell
        speakIt spk = new speakIt();
    
        do
        {
            string word = mngit.readFile();     // pass local checkSpell
            // etc
    
    class manageWords // Check file, open and edit it
    {
        public int lineNumber;
        private checkSpell ckt;
    
        public manageWords(checkSpell)
        {
            ckt = checkSpell;
        }
    
        //Check if file exists
        public string readFile()
        {
            // etc
    

    【讨论】:

      【解决方案3】:

      你的设计有缺陷。

      您有checkSpell 类创建manageWords 的实例并从您的checkSpell.getWord() 内部调用manageWords.readFile()。问题是您的manageWords.readFile() 正在创建checkSpell 的新实例。

      它永远不会与您正在查看或期待的实例进行交互。

      您可以快速完成以下操作,可能满足您的需求,但可能不适用于整个程序的结构。

      更改manageWords.readFile() 以接收checkSpell 的实例并使用它而不是创建一个新实例。

      public string readFile(checkSpell chkSpell)
      {
          string CurrentLine = "";
          int count = 0;
      
          try
          {
              ....
              if (lineNumber < count)
              {
                  CurrentLine = lines.Skip(lineNumber).First();
                  lineNumber++;
              }
              else 
              {
                  chkSpell.NoMoreWords = true;
                  ....
              } 
              ....
          }
          ....
       }
      

      然后从您的checkSpell.getWord() 致电您的readFile(),如下所示:mngit.readFile(this);

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-04-03
        • 1970-01-01
        • 1970-01-01
        • 2019-05-09
        • 2017-01-15
        • 1970-01-01
        相关资源
        最近更新 更多