[英]C# error CS0103 when using methods in different classes
我是C#的新手,不是英语(对此很抱歉); 我正在使用WinForm应用程序使用Visual Studio 2017。
为了测试要在现有项目中添加的某些功能,我创建了一个新的Winform应用程序。 这个简单的软件可以在文件中读写字符串。 因此,在表单中,我有2个文本框和3个按钮:保存到文件,从文件读取和更新。 为了减少较大项目中的混乱,我决定将方法分为不同的类:每个方法都完成一项工作,并且表单脚本具有尽可能少的代码量。 3个.cs文件(分类)为:
已创建所有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.