【问题标题】:Designing Fluent interface methods设计 Fluent 接口方法
【发布时间】:2012-04-14 22:47:47
【问题描述】:

我正在尝试编写 DSL

我有返回字符串的方法,但如果我想组合字符串,我需要使用 + 符号,但我想一起调用这些方法,但我不确定如何实现它

我现在有方法,比如

MyStaticClass.Root() MyStaticClass.And() MyStaticClass.AnyInt() 返回字符串

我希望能够做到

Root().And().AnyInt() 产生一个字符串

【问题讨论】:

    标签: c# .net linq generics fluent-interface


    【解决方案1】:

    您不需要使用 + 符号。使用StringBuilderhttp://msdn.microsoft.com/en-us/library/system.text.stringbuilder.aspx

    示例

    StringBuilder builder = new StringBuilder();
    builder.Append("One string ").Append("Second string").Append("Another string");
    string final = builder.ToString();  
    

    如果您想要一个简单的自定义 FluentInterface,请使用以下内容:

    public class MyOwnStringBuilder
    {
       public StringBuilder Builder;
    
    
       public MyOwnStringBuilder()
       {
          this.Builder = new StringBuilder();
       }
    
       public static MyOwnStringBuilder Root
       {
         get{return new MyOwnStringBuilder();}
       }
    
       public string End
       {
         get{return Builder.ToString();}
       }
    
       public MyOwnStringBuilder And(string value)
       {
         Builder.Append(value);
         return this;
       }
    
       public MyOwnStringBuilder AnyInt(string value)
       {
          Builder.Append(value);
          return this;
       }
    }
    

    你会使用它:

    MyOwnStringBuilder.Root
           .And("some value")
           .AnyInt("some new value")
           .End;
    

    问候。

    【讨论】:

    • 您总是需要调用 end 吗?这也适用于网络应用程序,因此它是线程安全的。不确定静态如何为线程安全工作
    • 不错的答案;但是我会重命名这个类:-)
    • 是的,您应该调用 End,并且线程安全没有问题。 @phoog 我以问题中提议的名称命名它,但是是的,最好重命名它。
    • 感谢您的回答。不过,我不喜欢每次都打电话给 End 。我想虽然没有太多选择
    • End() 所以在 N 个链之后你告诉类返回值。对于像这样简单的 fluentinterfaces,使用 Root() 或 Start() 和 End() 是最佳实践方法。看看 StringBuilder,你可以链接,直到你调用 ToString(),这基本上是一个 End() 调用。接受作为答案,因为我提供了您想要的一切。
    【解决方案2】:

    这些方法应该返回一个包装类。这些方法也是包装类的实例方法。示例:

    class Fluent
    {
         private string _value;
         public Fluent And()
         {
             this._value += "whatever";
             return this;
         }
         public Fluent AnyInt()
         {
             this._value += "42";
             return this;
         }
         public override string ToString() { return _value; }
    }
    

    您还可以定义从 Fluent 到字符串的隐式或显式转换,而不是(或附加于)ToString() 覆盖。

    另外,对于生产代码,我会使用字符串生成器来避免多次调用Concat

    【讨论】:

    • 字符串生成器追加?得到结果的隐式转换是什么样的?这个线程也安全吗?
    • public static implicit operator string(Fluent f) { return f.ToString(); }。见msdn.microsoft.com/en-us/library/z5z9kes2.aspx
    • @Jon,除非您打算在多个线程中使用同一个实例,否则线程安全不是您应该担心的问题。 Fluent 接口通常在单个方法中使用,然后被丢弃。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-07
    • 2017-06-06
    • 1970-01-01
    • 1970-01-01
    • 2014-01-24
    • 1970-01-01
    相关资源
    最近更新 更多