我是一名完整的编程爱好者,我正在努力学习正确的代码设计。我试图学习如何使用访问器,但似乎无法使其正常运行。这就是我想要运行的:
class Classy
{
public void changeLine(string change)
{
Form1 form1 = new Form1();
form1.Line = change;
}
}
public partial class Form1 : Form
{
string line = "";
public string Line
{
get
{
return line;
}
set
{
line = value;
}
}
private void button2_Click(object sender, EventArgs e)
{
line = "";
string change = "cake";
Classy classy = new Classy();
classy.changeLine(change);
MessageBox.Show(line);
}
单击按钮时,显示空白文本。根据我的理解,这些是它采取的步骤:
为什么这不起作用?
答案 0 :(得分:4)
这种情况正在发生,因为您正在Form
方法上创建changeLine
的新实例。这个新实例与触发事件或点击按钮的实例不同。
为了使用正确的Form
引用,您可以将实际引用作为参数传递:
public void changeLine(Form1 form, string line) {
form.Line = line;
}
您可以像这样调用此方法(来自表单):
classy.changeLine(this, change);
this
是当前的Form1
实例,它是您要修改的实例。你不想创建一个新的。
答案 1 :(得分:1)
好。你有一个Form1
对象,它所代表的窗口和控件显示在屏幕上。单击一个按钮,它会调用一个方法。
line = "";
此line
是一个私有字段,恰好是Line
属性的支持字段。此时,访问line
字段或Line
属性将返回""
。
string change = "cake";
此方法的本地字符串。
Classy classy = new Classy();
好的,我们有一个名为Classy
的{{1}}类型的新对象。
classy
让我们来看看这个电话的作用:
classy.changeLine(change);
您现在有一个不同的 Form1 form1 = new Form1();
对象。如果你打电话给Form1
,你现在屏幕上会有两个窗口。
form1.Show()
设置此新的 form1.Line = change;
的{{1}}属性(以及Line
字段)。
我们现在返回调用方法:
line
显示原始 Form1
对象的MessageBox.Show(line);
字段的值。
要演示从课外设置的属性,您可以执行以下操作:
line
此处因为Form1
将自身(class Classy
{
public void changeLine(Form1 form1, string change)
{
form1.Line = change;
}
}
public partial class Form1 : Form
{
string line = "";
public string Line
{
get
{
return line;
}
set
{
line = value;
}
}
private void button2_Click(object sender, EventArgs e)
{
string change = "cake";
Classy classy = new Classy();
classy.changeLine(this, change);
MessageBox.Show(line);
}
}
引用正在运行的方法的对象)传递给Form1
,现在将使用其自己的this
属性。
可替换地:
classy
此处表单首先设置,然后在另一个对象中获取属性。
另请注意,对象可以使用自己的属性而不是支持字段:
Line
从内部来看,可以说,无论是使用字段还是属性都没有多大区别,但使用属性确实有一个优势,因为如果有一天你改变了这个更简单的属性(读取和写入一个字段,什么都不做)更复杂的一个(常见的情况包括对所有设置的验证检查,但你远远不限于此)然后你只需要改变定义属性的一个地方而不是使用它的地方,也许很多。
(看起来使用class LineStorer
{
private string _line;
public string Line
{
get { return _line; }
set { _line = value; }
}
}
public partial class Form1 : Form
{
private void button2_Click(object sender, EventArgs e)
{
var storer = new LineStorer();
storer.Line = "cake";
MessageBox.Show(storer.Line);
}
}
似乎比使用public partial class Form1 : Form
{
private string _line;
public string Line
{
get { return _line; }
set { _line = value; }
}
private void button2_Click(object sender, EventArgs e)
{
Line = "cake";
MessageBox.Show(Line);
}
}
更多的工作,因为它在调用更多代码之后会执行,因此使用属性而不是字段会产生轻微的低效率随着时间的推移加起来。幸运的是,抖动非常聪明,可以在代码运行时“内联”简单的getter和setter,因此实际上没有成本)。
答案 2 :(得分:0)
你所做的就是你得到的。您希望显示line
的值,但在显示之前从未将其设置为其他值。无论你在这三行代码中做什么,都与更改line
在本课程表1的特定实例中的值无关。
string change = "cake";//You declare and initialize a variable
Classy classy = new Classy();//You create an instance of class Classy
classy.changeLine(change);//You invoke a method in that class that has no clue of what is going on this side
是的,它确实将line
的值设置为" cake",但是另一个对象。但是您仍然可以获得至少所需的行为两种方式:
您可以在Form1类型的Classy类中拥有一个实例变量,并且有一个构造函数可以接收Form1对象作为参数。然后在您的changeLine
方法中,您可以更改该特定实例变量的行,而不是创建一个全新的Form1对象,如下所示:
public class Classy{
private Form1 _form1;
public Classy(Form1 form1){
_form1=form1;
}
public void changeLine(string change){
_form1.Line=change;
}
}
您可以更改changeMethod
以接受Form1类型的其他参数,然后在Form1中调用它时将其传递给this
public void changeLine(string change,Form1 form1){
form1.line=change;
}
在Form1方面:
classy.changeLine("cake",this);