实施具有编译时顺序约束的功能处理管道

时间:2018-09-26 07:53:07

标签: c# design-patterns generic-programming

假设我们有一个数据对象X和一些“处理器”对象/方法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#中实现,以便在编译时强制执行顺序约束?如果没有,是否存在一种设计模式或一些通用的策略来实施该方法?可能有许多处理器和许多约束,我要避免的是必须声明一个阶乘类型,以跟踪处理器是否已运行。

1 个答案:

答案 0 :(得分:0)

您可以将继承与一般约束结合使用:

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