Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.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
C# 流畅的界面设计和代码气味_C#_Oop_Fluent Interface - Fatal编程技术网

C# 流畅的界面设计和代码气味

C# 流畅的界面设计和代码气味,c#,oop,fluent-interface,C#,Oop,Fluent Interface,基本上,我希望能够做到以下几点: public class StepClause { public NamedStepClause Action1() {} public NamedStepClause Action2() {} } public class NamedStepClause : StepClause { public StepClause Step(string name) {} } 因此,有些“步骤”已命名,有些则未命名 我不喜欢的是StepCla

基本上,我希望能够做到以下几点:

public class StepClause
{
    public NamedStepClause Action1() {}

    public NamedStepClause Action2() {}
}

public class NamedStepClause : StepClause
{
    public StepClause Step(string name) {}
}
因此,有些“步骤”已命名,有些则未命名

我不喜欢的是StepClause知道它的派生类名dstepClause

我试着做了几件事让这件事更适合我。 我试图将问题转移到接口上,但问题只是从具体问题转移到了接口上——INamedStepClause仍然需要从IStepClause派生,而IStepClause需要返回INamedStepClause才能调用Step()。 我还可以使Step()成为完全独立类型的一部分。那么我们就没有这个问题了,我们会:

var workflow = new Workflow().Configure()
    .Action1()
    .Step("abc").Action2()
    .Action2()
    .Step("def").Action1();
这是可以的,但是如果可能的话,我想让步骤命名成为可选的

我在网上找到了另一篇文章,看起来很有趣,也很有希望。 你的意见是什么?我认为最初的解决方案是完全不可接受的,是吗

顺便说一句,这些操作方法将使用谓词和函子,我不想使用额外的参数来命名那里的步骤


对我来说,这一切的意义在于只在一个地方和一个地方定义这些操作方法。因此,参考链接中使用泛型和扩展方法的解决方案似乎是目前为止最好的方法。

我将给您两个选项

方案A

var workflow = new Workflow().Configure()
    .Step().Action1()
    .Step("abc").Action2()
    .Step().Action2()
    .Step("def").Action1();
这两个选项都可以编译并为您提供所需的流畅界面。我更倾向于使用选项A,因为它可以让您访问类的内部工作。使用扩展方法意味着您可能需要为类提供某种外部访问,从而破坏封装


祝你好运

我只是不喜欢我得到的大多数答案。另一个原因是我忘记了;PI将采用选项A,并在NamedStepClause中更改Step方法-它应该返回StepClause而不是NamedStepClause;否则,我会陷入一种你可以做的情况:步骤(“1”)。步骤(“2”)。步骤(“3”)。。。也许这个要求并不清楚- SyRype B不适用于我在上面的评论中所说的相同的原因。我从C++时代以来就没有见过这样的模板/通用魔术。不错
var a = new A.NamedStepClause();

a.Action1()
    .Step("abc").Action2()
    .Action2()
    .Step("def").Action1();


namespace A
{
    public class StepClause<SC> where SC : StepClause<SC>
    {
        public SC Action1() { return null; }
        public SC Action2() { return null; }
    }

    public class NamedStepClause : StepClause<NamedStepClause>
    {
        public NamedStepClause Step(string name) { return null; }
    }
}
var b = new B.StepClause();

b.Action1()
    .Step("abc").Action2()
    .Action2()
    .Step("def").Action1();

namespace B
{
    public class StepClause
    {
        public StepClause Action1() { return null; }
        public StepClause Action2() { return null; }
    }

    public static class StepClauseExtensions
    {
        public static StepClause Step(this StepClause @this, string name)
        { return null; }
    }
}