实现具有编译时顺序约束的功能处理管道
Implement a functional processing pipeline with compile-time order constraints
假设我们有一个数据对象 X 和一些 "processor" objects/methods A、B、C 和 D。A(X) 生成一个带有一些附加数据的新 X(A 的结果加工)。 B(X) 生成一个带有一些其他附加数据的新 X。 C(X) 也会产生一个带有一些额外数据的新 X,但它要求 A 已经 运行 反对 X。
所以:A(X).B(X).C(X).D(X) 应该 运行 正确。 B(X).D(X).A(X).C(X) 也应该 运行 正确。 B(X).C(X).A(X).D(X) 应该失败(因为 C 需要 A 产生的信息)。
这是否可以在 C# 中实现,以便在编译时强制执行顺序约束?如果没有,是否有设计模式或一些通用策略来实现这一点?可以有很多处理器和很多约束,我想避免的是必须声明一个类型的阶乘数来跟踪处理器是否 运行。
您可以使用继承,结合泛型约束:
class Data {
}
class ExtendedData : Data {
}
static class Pipeline {
public static ExtendedData A<T>(this T value) where T : Data {
if (value is ExtendedData extended) {
return extended;
}
else {
return new ExtendedData():
}
}
public static T B<T>(this T value) where T : Data {
return value;
}
public static ExtendedData C(this ExtendedData value) {
return value;
}
}
这些变体将起作用:
new Data().A().B().C();
new Data().B().A().C();
new Data().A().C().B();
此变体将被编译器拒绝:
new Data().B().C().A();
C()
会期望 ExtendedData
,而 B()
只会提供 Data
.
假设我们有一个数据对象 X 和一些 "processor" objects/methods A、B、C 和 D。A(X) 生成一个带有一些附加数据的新 X(A 的结果加工)。 B(X) 生成一个带有一些其他附加数据的新 X。 C(X) 也会产生一个带有一些额外数据的新 X,但它要求 A 已经 运行 反对 X。 所以:A(X).B(X).C(X).D(X) 应该 运行 正确。 B(X).D(X).A(X).C(X) 也应该 运行 正确。 B(X).C(X).A(X).D(X) 应该失败(因为 C 需要 A 产生的信息)。
这是否可以在 C# 中实现,以便在编译时强制执行顺序约束?如果没有,是否有设计模式或一些通用策略来实现这一点?可以有很多处理器和很多约束,我想避免的是必须声明一个类型的阶乘数来跟踪处理器是否 运行。
您可以使用继承,结合泛型约束:
class Data {
}
class ExtendedData : Data {
}
static class Pipeline {
public static ExtendedData A<T>(this T value) where T : Data {
if (value is ExtendedData extended) {
return extended;
}
else {
return new ExtendedData():
}
}
public static T B<T>(this T value) where T : Data {
return value;
}
public static ExtendedData C(this ExtendedData value) {
return value;
}
}
这些变体将起作用:
new Data().A().B().C();
new Data().B().A().C();
new Data().A().C().B();
此变体将被编译器拒绝:
new Data().B().C().A();
C()
会期望 ExtendedData
,而 B()
只会提供 Data
.