我有以下包装类:
public class Wrapper
{
public int Member;
}
在另一个课程中,我有以下内容:
public class ContainerClass
{
private Wrapper data;
public Wrapper Property
{
get { return data; }
set { data = value; }
}
public void Foo()
{
Property.Member = 42;
}
}
在Property.Member
中修改Foo()
时,没有任何反应(跳过设置者)。但是,我仍然可以执行以下操作,例如:
public void Foo()
{
Property = Property;
}
并输入所需的setter。所以我的问题是,为什么不修改对象属性的成员调用该属性的setter?
答案 0 :(得分:1)
因为您没有修改引用。您正在修改引用'member。
比方说,如果我站在房间的角落里说“抱这个苹果”。如果我进来并用香蕉切换苹果..我没有换过你,所以你很高兴。但如果我和其他人一起出门,你会抱怨我要替换你。
..无论如何,这是我的比喻。
此外,您已经使用I
为类添加了前缀..这通常用于.NET域中的接口。
答案 1 :(得分:1)
因为您没有设置Property
的值。您的代码只调用Property
的getter,然后设置Member
字段的值(如果它是属性,将调用Member
的setter,这不是这里的情况)。
如果要在设置Member
时执行代码,则需要
public class Wrapper
{
private int member;
public int Member
{
get { return this.member; }
set
{
this.member = value;
DoSomething();
}
}
}
或许更优雅的解决方案是使用事件。内置的INotifyProperyChanged界面为您提供了一个非常好的模板。
using System.ComponentModel;
public class Wrapper : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private int member;
public int Member
{
get { return this.member; }
set
{
this.member = value;
this.OnPropertyChanged("Member");
}
}
protected void OnPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
}
public class ContainerClass
{
private Wrapper data;
public Wrapper Property
{
get { return data; }
set { data = value; }
}
public void Foo()
{
data.PropertyChanged += data_PropertyChanged;
Property.Member = 42;
}
private void data_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == "Member")
{
DoStuff();
}
}
}
答案 2 :(得分:0)
在foo的构造函数中,您正在设置类Wrapper的字段。
public void Foo()
{
Property.Member = 42; // No property set, you are accessing a field.
}
在第二个示例中,您正在设置属性
public void Foo()
{
// Setting Property "Property" to the value of "Property"
// You should see both the getter and the setter called.
Property = Property;
}
我不知道你要做什么,但也许你想让Wrapper拥有一个属性。
public class Wrapper
{
private int member;
public int Member
{
get { return data; }
set { data = value; }
}
}
然后当你做Property.Member = 42时,会在Wrapper.Member上调用setter。
答案 3 :(得分:0)
通常人们通过Add()方法直接将对象添加到列表中,而该方法又不会触发setter。
private List<string> _namesList = new List<string>();
// list of names
public List<string> NamesList
{
get
{
return _namesList;
}
set
{
if (value == _namesList)
{
return;
}
_namesList = value;
}
}
在上面的NamesList属性中,如果你调用NamesList.Add(&#34; test&#34;),它就不会调用setter。简单的解决方案是将列表存储在一个新变量中,并逐渐将该变量设置为NamesList,例如
List<string> lst = new List<string>{ "test1" };
d.NamesList = lst; // setter will fire.
但是直接将对象添加到列表/集合中是一个常见的错误。 :)