Dart抽象可选参数

Dart抽象可选参数,dart,Dart,如何抽象出一个方法具有可选参数 抽象类CopyWith{ T copyWith({});//错误:应为标识符。 } 如果我添加一个标识符,比如{test},它会工作,子类可以有额外的参数 我想要实现什么? 我有一个复杂的状态管理器,我做了一些抽象,下面的代码是一个最小的代码,显示我的问题 导入“dart:collection”; 抽象类CopyWith{ T copyWith(可选的命名参数); } 抽象类管理器{ final_map=HashMap(); 添加(K键,V值){ _映射[键]=

如何抽象出一个方法具有可选参数

抽象类CopyWith{
T copyWith({});//错误:应为标识符。
}
如果我添加一个
标识符
,比如
{test}
,它会工作,子类可以有额外的参数

我想要实现什么? 我有一个复杂的状态管理器,我做了一些抽象,下面的代码是一个最小的代码,显示我的问题

导入“dart:collection”;
抽象类CopyWith{
T copyWith(可选的命名参数);
}
抽象类管理器{
final_map=HashMap();
添加(K键,V值){
_映射[键]=值;
}
void copyWith(K键,可选参数){
断言(key!=null);
如果(_map.containsKey(键)){
_map[key].copyWith(可选的参数);
}
}
}
类用户实现CopyWith{
最终int id;
最后的字符串名;
用户({this.id,this.name});
用户copyWith({int-id,String-name}){
返回用户(
id:id??这个,
name:name??this.name,
);
}
}
类UserManager扩展管理器{}
void main(){
final userManager=userManager();
add(1,User(1,'test');
copyWith(1,{test:'test2'})
}

作为在我的库中遇到过这个问题的人,我想说的唯一方法是不要在基类中放置
copyWith

为什么??因为只有当存在共享调用约定和行为时,才应该使函数具有多态性。在您的示例中,这两个类执行
copyWith
的方式完全不同。将
名称
发送到
管理器.copyWith
是错误的,而且应该是错误的,因为
管理器
没有
名称
。如果在
管理器.copyWith
中遇到名称,则表示代码中存在严重错误

此外,如果您作为一名负责任的程序员实际尝试调用
copyWith
,您可能会检查是否允许传递
名称,即

if(someObj是用户){
someObj.copyWith(键,名称:name);
}否则如果(someObj是经理){
抛出IllegalStateError('你不应该把名字传给经理!我现在该怎么处理这个名字?');
}
在这里,您已经完成了类型检查,因此无需将
copyWith
设置为多态



然而,一些常见的行为可以是多态的,比如
updateKey
。您可以将
Keyable
作为一个接口,将
Keyable updateKey(Key)
作为一个抽象方法,并将其委托给每个子类内部的非多态
copyWith

您的基类不接受任何命名参数(实际上根本没有参数)。它可以是
T copyWith()。如果我设置为
copyWith()
,我在其他代码中有错误,例如
copyWith c
是我在方法中的参数,我想调用并传递参数
c.copyWith(x:'y')
@jamesdlin我添加了一些代码您无法将参数(可选或非可选)传递给未声明接受它们的方法或函数。也就是说,如果
c
被声明为
Foo
类型,则不能使用
Foo.copyWith
未声明接受的参数调用
c.copyWith
。无论您是否有0个参数或1个参数,无论它们是可选的还是命名的。这就是静态类型检查的工作原理。如果您知道
c
属于派生类型,则必须首先将其强制转换为该类型。或者,您可以禁用静态类型检查:
(c为动态).copyWith(x:'y')
,并假设调用的
c.copyWith
的任何实现都采用命名的
x
参数。(当然,如果没有,它会抛出一个错误。)你能给我举个例子吗?我这里的例子非常简单,假设抽象类中的
copyWith
有许多公共逻辑,我必须在子类中复制这些逻辑,比如
if(_map.containsKey(key))
有一些很好的Dart代码生成器,可以为类生成
copyWith
,以及其他函数<例如,VSCode上的code>Dart数据类
。如果您真的对这种方式不满意,可以让
copyWith
Map
作为参数,并按名称提取参数。但是
Object
将取消任何类型安全并破坏性能,这是使
copyWith
共享的成本。此外,一个好的代码生成器还可以为您生成
操作符==
hashCode
toJson
toMap
,如果您试图在基类中实现它们,这简直是疯了。在我看来,
copyWith
与那些方法是一样的。我不只是考虑
copyWith
,我想让一个父类保留所有公共逻辑,我不想在子类中重复主题。在这种情况下,您应该分解这些行为,只提取最大的公共共享行为作为基类中的实用程序方法。这是OOP设计领域中的一种,只能在个案的基础上进行。但不要对样板太紧张,飞镖和颤振从来都不是为了简洁而设计的。