繁体   English   中英

在不同类中使用方法时,C#错误CS0103

[英]C# error CS0103 when using methods in different classes

我是C#的新手,不是英语(对此很抱歉); 我正在使用WinForm应用程序使用Visual Studio 2017。

为了测试要在现有项目中添加的某些功能,我创建了一个新的Winform应用程序。 这个简单的软件可以在文件中读写字符串。 因此,在表单中,我有2个文本框和3个按钮:保存到文件,从文件读取和更新。 为了减少较大项目中的混乱,我决定将方法分为不同的类:每个方法都完成一项工作,并且表单脚本具有尽可能少的代码量。 3个.cs文件(分类)为:

  • 表单局部类,
  • SaveFile类,用于执行将字符串保存到文本文件的工作,
  • OpenFile类,在其中读取文本文件的作业返回字符串列表中的行。

已创建所有3个类,并将它们添加到项目ProvaSalvataggioFile2中。

因此,表单类是(请注意方法的名称,如果有人想测试代码,我已经写了所有代码以确保完整性)

using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;

namespace ProvaSalvataggioFile2
{
    public partial class MainForm : Form
    {
        public MainForm()
        {
            InitializeComponent();
        }

        private void btnSave_Click(object sender, EventArgs e)
        {
            string inputString = tbInputText.Text;
            if (inputString.IsValidString())
            {
                inputString.SaveToFile();
            }
            else
            {
                MessageBox.Show("The input string is not valid: please insert a valid string",
                    "Empty or null input string",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Exclamation);
                tbInputText.Focus();
            }
        }

        private void btnOpenFile_Click(object sender, EventArgs e)
        {
            List<string> textFileContent = new List<string>();
            textFileContent = OpenTextFile();
            tbFileText.Text = string.Join(Environment.NewLine, textFileContent);
        }

        private void btnUpdate_Click(object sender, EventArgs e)
        {
            if (File.Exists(fileName))
            {
                List<string> textReadFromFile = new List<string>();
                textReadFromFile = File.ReadAllLines(fileName).ToList();
                tbFileText.Text = string.Join(Environment.NewLine, textReadFromFile);
            }
        }
    }
}

SaveFile类是

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;

namespace ProvaSalvataggioFile2
{
    public static class SaveFile
    {
        public static bool IsValidString(this string stringToValidate)
        {
            bool result = true;
            if (string.IsNullOrEmpty(stringToValidate))
            {
                result = false;
            }
            return result;
        }

        public static bool SaveToFile(this string stringToSave)
        {
            bool result = true;
            //bool savedfile;
            DialogResult messageBoxResult;

            SaveFileDialog saveFileDialog1 = new SaveFileDialog();
            //saveFileDialog1.InitialDirectory = @"C:\";
            saveFileDialog1.Title = "Save text Files";
            saveFileDialog1.CheckFileExists = false;
            saveFileDialog1.OverwritePrompt = false;
            saveFileDialog1.CheckPathExists = true;
            saveFileDialog1.DefaultExt = "txt";
            saveFileDialog1.Filter = "Text files (*.txt)|*.txt|All files (*.*)|*.*";
            saveFileDialog1.FilterIndex = 1;
            saveFileDialog1.RestoreDirectory = true;
            if (saveFileDialog1.ShowDialog() == DialogResult.OK)
            {
                if (File.Exists(saveFileDialog1.FileName))
                {
                    messageBoxResult = MessageBox.Show("The file is already existing: do you want:\n\t\u22c5OVERWRITE the file [YES]\n\t\u22c5APPEND data in the file [NO]\n\t\u22c5Use another file [CANCEL]",
                        "Overwrite file",
                        MessageBoxButtons.YesNoCancel,
                        MessageBoxIcon.Asterisk,
                        MessageBoxDefaultButton.Button3);
                    if (messageBoxResult == DialogResult.Yes)
                    {
                        messageBoxResult = MessageBox.Show(("Are you sure to overwrite the file in\n" + saveFileDialog1.FileName),
                            "Sure to overwrite file?",
                            MessageBoxButtons.OKCancel);
                        if (messageBoxResult == DialogResult.OK)
                        {
                            try
                            {
                                File.WriteAllText(saveFileDialog1.FileName, stringToSave);
                                result = true;
                            }
                            catch
                            {
                                result = false;
                            }
                        }
                    }
                    else if (messageBoxResult == DialogResult.No)
                    {
                        //MessageBox.Show(("Message to save: \"" + stringToSave + "\"\nin \"" + saveFileDialog1.FileName));
                        try
                        {
                            File.AppendAllText(saveFileDialog1.FileName, (Environment.NewLine + stringToSave));
                            result = true;
                        }
                        catch
                        {
                            result = false;
                        }
                    }
                    else
                    {
                        messageBoxResult = MessageBox.Show("Please enter a new filename",
                            "Save in a new file",
                            MessageBoxButtons.OKCancel);
                        if (messageBoxResult == DialogResult.OK)
                        {
                            stringToSave.SaveToFile();
                        }
                    }
                }
                else
                {
                    File.WriteAllText(saveFileDialog1.FileName, stringToSave);
                    result = true;
                }
            }

            return result;
        }
    }
}

OpenFile类是:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;

namespace ProvaSalvataggioFile2
{
    public class OpenFile
    {
        public string fileName { get; set; }

        public List<string> OpenTextFile()
        {
            List<string> textReadFromFile = new List<string>();
            //textReadFromFile = new List<string>();
            OpenFileDialog openFileDialog1 = new OpenFileDialog();
            openFileDialog1.CheckPathExists = true;
            openFileDialog1.CheckFileExists = true;
            openFileDialog1.RestoreDirectory = true;
            openFileDialog1.Filter = "Text files (*.txt)|*.txt|All files (*.*)|*.*";
            openFileDialog1.FilterIndex = 1;
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                fileName = openFileDialog1.FileName.ToString();
                textReadFromFile = File.ReadAllLines(openFileDialog1.FileName).ToList();
            }
            return textReadFromFile;
        }
    }
}

现在,如果我将所有方法都放在表单类中,则所有工作都很好,没有问题(应用程序很愚蠢,只是为了测试后面的逻辑而已)。 但是,如果我将代码分为3个类,则有:

  • 错误CS0103当前上下文中不存在名称'OpenTextFile'ProvaSalvataggioFile2 Form1.cs 41
  • 错误CS0103名称'fileName'在当前上下文中不存在ProvaSalvataggioFile2 Form1.cs 47
  • 错误CS0103名称'fileName'在当前上下文中不存在ProvaSalvataggioFile2 Form1.cs 50

因此,必须存在一些与类拆分有关的问题。 我曾尝试使用Google搜索该错误,但似乎该错误是在非常不同的情况下以及由于不同的原因(与我的共同点)而出现的。 我认为在添加新类或定义该类的代码中我错过了一些东西。

我再说一遍,如果我将这些方法复制并粘贴到表单类中,则该应用程序可以正常运行,但是放在单独的类中的相同方法(但是在表单类的同一文件中)则无效。

这里的问题是您试图访问MainForm类中的OpenFile类的成员。 初始化OpenFile实例,并将其保留在MainClass中的变量中以重用

using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;

namespace ProvaSalvataggioFile2
{
    public partial class MainForm : Form
    {
        // Initialize OpenFile
        private readonly OpenFile openFile = new OpenFile();
        public MainForm()
        {
            InitializeComponent();
        }

        private void btnSave_Click(object sender, EventArgs e)
        {
            string inputString = tbInputText.Text;
            if (inputString.IsValidString())
            {
                inputString.SaveToFile();
            }
            else
            {
                MessageBox.Show("The input string is not valid: please insert a valid string",
                    "Empty or null input string",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Exclamation);
                tbInputText.Focus();
            }
        }

        private void btnOpenFile_Click(object sender, EventArgs e)
        {
            List<string> textFileContent = new List<string>();
            textFileContent = openFile.OpenTextFile(); // Open Text File via openFile variable
            tbFileText.Text = string.Join(Environment.NewLine, textFileContent);
        }

        private void btnUpdate_Click(object sender, EventArgs e)
        {
            if (File.Exists(openFile.fileName)) // Validate file exists via openFile.fileName property
            {
                List<string> textReadFromFile = new List<string>();
                textReadFromFile = File.ReadAllLines(fileName).ToList();
                tbFileText.Text = string.Join(Environment.NewLine, textReadFromFile);
            }
        }
    }
}

您还可以通过将IsValidString方法更改为扩展方法来减少代码

public static bool IsValidString(this string stringToValidate) => !string.IsNullOrEmpty(stringToValidate)

我建议您重新设计代码,因为使用一个类IE OpenFile打开和检查文件内容可能会发现潜在的错误。 例如,如果没有打开文件并且fileName是一个空字符串,该怎么办。

请参阅以下有关类的MSDN文章 ,以更深入地了解它们以及如何进行交互。

重构代码

我对代码进行了重构,使其更加易于管理和可读,请参见下文。

这是一个名为TextFile的新类,您可以在其中存储文件名和内容。

namespace ProvaSalvataggioFile2
{
    public class TextFile
    {
        public TextFile(string fileName, string contents)
        {
            FileName = fileName;
            Contents = contents;
        }

        public string FileName { get; set; }
        public string Contents { get; set; }
    }
}

您的OpenFile类实际上命名得很好,它具有很好的关注点分离-意味着乍一看,我可以看到它是只应用于打开文件的类,尽管您可以更进一步并抽象UI代码,将您带到Win Forms。 OpenTextFile现在返回一个TextFile对象

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;

namespace ProvaSalvataggioFile2
{
    public class OpenFile
    {
        public TextFile OpenTextFile()
        {
            TextFile textFile;
            OpenFileDialog openFileDialog1 = new OpenFileDialog();
            openFileDialog1.CheckPathExists = true;
            openFileDialog1.CheckFileExists = true;
            openFileDialog1.RestoreDirectory = true;
            openFileDialog1.Filter = "Text files (*.txt)|*.txt|All files (*.*)|*.*";
            openFileDialog1.FilterIndex = 1;
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                string fileName = openFileDialog1.FileName.ToString();
                string textReadFromFile = File.ReadAllText(openFileDialog1.FileName);

                textFile = new TextFile(fileName, textReadFromFile);
            }
            return textFile;
        }
    }
}

当然,必须对MainForm进行更新以考虑新对象,我删除了重复的代码,重新使用了OpenFile类,并引入了RefreshTextFile方法来设置标签文本-这次您不必担心文件名称有效。

using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;

namespace ProvaSalvataggioFile2
{
    public partial class MainForm : Form
    {
        private readonly OpenFile openFile = new OpenFile();
        public MainForm()
        {
            InitializeComponent();
        }

        private void btnSave_Click(object sender, EventArgs e)
        {
            string inputString = tbInputText.Text;
            if (inputString.IsValidString())
            {
                inputString.SaveToFile();
            }
            else
            {
                MessageBox.Show("The input string is not valid: please insert a valid string",
                    "Empty or null input string",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Exclamation);
                tbInputText.Focus();
            }
        }

        private void btnOpenFile_Click(object sender, EventArgs e)
        {
            RefreshTextFile();
        }

        private void btnUpdate_Click(object sender, EventArgs e)
        {
            RefreshTextFile();
        }

        private void RefreshTextFile()
        {
            TextFile textFile = openFile.OpenTextFile();
            tbFileText.Text = textFile?.Contents;
        }
    }
}

请注意,我已经使用Notepad ++对其进行了重构,还没有通过编译器进行处理。

您的Form类不知道OpenTextFile()在哪里或什么,fileName也是如此。 您需要创建要使用的对象的实例。 尝试将此代码添加到MainForm中:

    private OpenFile _openFile;

    public MainForm()
    {
        this._openFile = new OpenFile();
        InitializeComponent();
    }

这将创建MainForm现在可以使用的OpenFile类的新实例。

您也可以将OpenFile设为静态,但这不是最佳实践。

请注意,由于未初始化OpenFile.fileName,因此您可能还想添加类似的内容。

public OpenFile(string initialFileName = "defaultFilename"){
    this.fileName = initialFileName;
}

您甚至可以通过提供MainFile作为参数来指定文件名。 或者,如果您不想设置参数,则可以在读取/使用fileName之前执行null检查。

有关对象和构造函数的更多信息,请参见: https : //docs.microsoft.com/zh-cn/dotnet/csharp/programming-guide/classes-and-structs/objects

https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/constructors

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM