Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/.htaccess/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
是否可以为dart中的内部(嵌套)字段添加setter?_Dart - Fatal编程技术网

是否可以为dart中的内部(嵌套)字段添加setter?

是否可以为dart中的内部(嵌套)字段添加setter?,dart,Dart,在dart中,当字段的值更改时,我们可以使用 class Name{ String fname; String lname; } class Person extends ChangeNotifier{ Name _name = Name(); set name(Name n){ notifyListeners(); _name = n; } get name=>_name; } //inside main() Person p = Person

在dart中,当字段的值更改时,我们可以使用

class Name{
  String fname;
  String lname;
}
class Person extends ChangeNotifier{
  Name _name = Name();
  set name(Name n){
    notifyListeners();
    _name = n;
  }
  get name=>_name;
}

//inside main() 
Person p = Person();
p.name = Name();
我希望能够在设置内部字段时执行类似的操作。比如在做的时候

p.name.fname ="FooBar";
但我希望能够在
个人
课堂上完成

因为我在Person类中扩展了
ChangeNotifier
。我想打电话

notifyListeners()
在名称类中不可访问的。这是我想到的最好的

Name newName = Name(p.name); //copy constructor
newName.fname = "Foo Bar";
p.name = newName;

有更好的方法吗?

您可以做什么取决于如何约束API

如果
Name
对象通常是由第三方代码创建并传递的,并且当存储在
Person
对象中时,希望保留它们的身份,那么您就无能为力了。所以我不会那样设计Person对象

相反,我要说的是
Person
对象的
Name
对象链接到该对象,设置
Person
Name
与设置两个名称部分相同

例如:

class Person {
  _PersonName _name;
  Person(...) : ... {
    _name = _PersonName(this);
  }
  ...
  void set name(Name name) {
    _name.fname = name.fname;
    _name.lname = name.lname;
    notifyListeners();
  }
  Name get name => _name;
}

class _PersonName extends Name {
  final Person _owner;
  _PersonName(this._owner);
  void set fname(String fname) {
    super.fname = fname;
    _owner.notifyListeners();
  }
  void set lname(String lname) {
    super.lname = lname;
    _owner.notifyListeners();
  }
}
这样做的缺点是提取的
\u PersonName
永远链接到
Person
对象,即使您尝试编写不同的
名称
对象

另一个选项是在每个存储上创建一个新的
\u PersonName
,并在该点将旧对象与
Person
分离:

class Person {
  _PersonName _name = _PersonName;
  Person(...) : ... {
    _name = _PersonName(this, null, null);
  }
  void set name(Name name) {
    _name.owner = null;
    _name = _PersonName(this, name.fname, name.lname);
    notifyListeners();
  } 
  Name get name => _name;
}
class _PersonName extends Name {
  Person _owner;
  _PersonName(this._owner, String fname, String lname) {
    super.fname = fname;
    super.lname = lname;
  }
  void set fname(String fname) {
    super.fname = fname;
    owner?.notifyListeners();
  }
  void set lname(String lname) {
    super.lname = lname;
    owner?.notifyListeners();
  }
}
此方法的行为与普通存储名称对象非常相似,除非您执行以下操作:

var p=Person(); var n=Name(); p、 name=n; 打印(相同的(n,p.name));//假的

您不保留存储在
Person
对象中的
Name
对象的标识。
没有办法做到这一点,而且还改变了使用
person.name.fname=…
直接在名称上设置字符串的行为,因此必须牺牲一些东西。

这显然是比我现有的更好的方法。但我得说实话,一开始很难理解。