2013-01-09 10 views
6

Dartプログラミング言語はmethod cascadesをサポートしています。メソッドのカスケードは、次のSilverlight/WPF C#のコードを可能にする:としてC#のシミュレーション方法カスケード

var listBox = new ListBox(); 

listBox.Width = 200; 
listBox.MouseEnter += (s, e) => Console.WriteLine("MouseEnter"); 

var button1 = new Button() { Content = "abc" }; 
button1.Click += (s, e) => Console.WriteLine("button1.Click"); 

listBox.Items.Add(button1); 

var button2 = new Button() { Content = "def" }; 
button2.Click += (s, e) => Console.WriteLine("button2.Click"); 

listBox.Items.Add(button2); 

ContentPanel.Children.Add(listBox); 

が代わりに書き込まれるように:私の質問がある

ContentPanel.Children.Add(
    new ListBox() 
     ..Width = 200 
     ..MouseEnter += ((s, e) => Console.WriteLine("MouseEnter")) 
     ..Items.Add(
      new Button() 
       ..Content = "abc"; 
       ..Click += ((s, e) => Console.WriteLine("button 1 Click"))) 
     ..Items.Add(
      new Button() 
       ..Content = "def"; 
       ..Click += (s, e) => (Console.WriteLine("button 2 Click")))); 

、C#で近似法カスケードをシミュレートまたは密接にする方法は何ですか?

私が思いついたアプローチは次のとおりです。この拡張メソッドを考えると次のように

public static T Call<T>(this T obj, Action<T> proc) 
{ 
    proc(obj); 

    return obj; 
} 

上記の例では、書くことができます。

ContentPanel.Children.Add(
    new ListBox().Call(o => { 
      o.Width = 200; 
      o.MouseEnter += (s, e) => Console.WriteLine("MouseEnter"); 
      o.Items.Add(
       new Button().Call(b => { 
         b.Content = "abc"; 
         b.Click += (s, e) => Console.WriteLine("button 1 Click"); })); 
      o.Items.Add(
       new Button().Call(b => { 
        b.Content = "def"; 
        b.Click += (s, e) => Console.WriteLine("button 2 Click"); })); })); 

私はかなりだと主張しません。 :-)しかし、基本的に流暢なスタイルを適用することができます。

+1

を必要に応じて、私に教えてください、あなたは、単に[オブジェクト初期化子](http://msdn.microsoft.com/en-us/library/vstudio/bb384062.aspx)を探していませんか? –

+2

@SimonWhiteheadオブジェクトイニシャライザはプロパティでのみ動作します。この例には、イベントとメソッド呼び出しが含まれています。 – juharr

+3

私はあなたが持っているものは、あなたが得ることができるほど近くにあると思います。そして、私は正直なところ、あなたのダーツの例よりはるかに醜いとは思わない。 – juharr

答えて

3

私はあなたが流暢なインターフェイスを使用して達成したいものに近づけることができると思います。 1つのステートメントでオブジェクトを作成して初期化するメソッドをチェーンすることができます。

あなたはそのような何かを得ることができます。

Fluent fluent = new Fluent(); 
var panel = fluent.CreateControlPanel().Children() 
       .AddListBox().SetWidth(200).AddMouseEnterEvent((s, e) => { }).Create() 
       .AddTextBox().SetText("Foo").Create() 
       .GetControlPanel(); 

アイデアは、メソッドが別のオブジェクトを初期化できるようにするオブジェクトを返すことです。イニシャライザのチェーンは、元のオブジェクト(Children以上)を返す "ファイナライザ"メソッド(上記のCreate)を呼び出すことで、他のオブジェクトの追加や初期設定を継続できます。

たとえば、AddListBoxは、SetWidthまたはAddMouseEnterEventのような一連のメソッドを持つタイプListBoxSetupのオブジェクトを返します。この場合、ChildrenAddListBoxAddTextBoxのような一連のメソッドを持つ特別なオブジェクト(タイプなど)になります。それぞれのメソッドは、タイプListBoxまたはTextBoxのオブジェクトを作成するか、または作成する基本オブジェクトの設定プロパティを担当します。 Fluentには、オブジェクト構造全体を正しくセットアップする方法があります。

は、このリンクを見てみましょう: http://blog.raffaeu.com/archive/2010/06/26/how-to-write-fluent-interface-with-c-and-lambda.aspx

をここで基礎となるコードの例です上記で終わるために作成します。もちろん、コードはアーキテクチャで大幅に改善される可能性がありますが、例のためだけです。

public class Fluent 
{ 
    public ControlPanelCreator CreateControlPanel() 
    { 
     return new ControlPanelCreator(new StackPanel(), this); 
    } 
} 

public class ControlPanelCreator 
{ 
    #region Fields 
    private Fluent fluent; 
    private Panel panel; 
    #endregion 

    #region Constructors 
    internal ControlPanelCreator(Panel panel, Fluent fluent) 
    { 
     this.fluent = fluent; 
     this.panel = panel; 
    } 
    #endregion 

    #region Methods 
    public ControlPanelChildrenCreator Children() 
    { 
     return new ControlPanelChildrenCreator(this.panel, this); 
    } 
    #endregion 
} 

public class ControlPanelChildrenCreator 
{ 
    #region Fields 
    private ControlPanelCreator panelCreator; 
    private Panel panel; 
    #endregion 

    #region Constructors 
    internal ControlPanelChildrenCreator(Panel panel, ControlPanelCreator panelCreator) 
    { 
     this.panel = panel; 
     this.panelCreator = panelCreator; 
    } 
    #endregion 

    #region Methods 
    public ListBoxCreator AddListBox() 
    { 
     ListBox listBox = new ListBox(); 
     this.panel.Children.Add(listBox); 
     return new ListBoxCreator(listBox, this); 
    } 

    public TextBoxCreator AddTextBox() 
    { 
     TextBox textBox = new TextBox(); 
     this.panel.Children.Add(textBox); 
     return new TextBoxCreator(textBox, this); 
    } 

    public Panel GetControlPanel() 
    { 
     return this.panel; 
    } 
    #endregion 
} 

public class ListBoxCreator 
{ 
    #region Fields 
    private ListBox listbox; 
    private ControlPanelChildrenCreator parentCreator; 
    #endregion 

    #region Constructors 
    internal ListBoxCreator(ListBox listBox, ControlPanelChildrenCreator parentCreator) 
    { 
     this.listbox = listBox; 
     this.parentCreator = parentCreator; 
    } 
    #endregion 

    #region Methods 
    public ListBoxCreator SetWidth(int width) 
    { 
     this.listbox.Width = width; 
     return this; 
    } 

    public ListBoxCreator AddMouseEnterEvent(Action<object, MouseEventArgs> action) 
    { 
     this.listbox.MouseEnter += new MouseEventHandler(action); 
     return this; 
    } 

    public ControlPanelChildrenCreator Create() 
    { 
     return this.parentCreator; 
    } 
    #endregion 
} 

public class TextBoxCreator 
{ 
    #region Fields 
    private TextBox textBox; 
    private ControlPanelChildrenCreator parentCreator; 
    #endregion 

    #region Constructors 
    internal TextBoxCreator(TextBox textBox, ControlPanelChildrenCreator parentCreator) 
    { 
     this.textBox = textBox; 
     this.parentCreator = parentCreator; 
    } 
    #endregion 

    #region Methods 
    public TextBoxCreator SetText(string defaultText) 
    { 
     this.textBox.Text = defaultText; 
     return this; 
    } 

    public ControlPanelChildrenCreator Create() 
    { 
     return this.parentCreator; 
    } 
    #endregion 
} 
0

私は以前の回答を支持しました。同じ種類のものを作ったので、私が追加したいことはほとんどありません。

2つのことがあります.1つのクラスで作業していることです。フォームを意味し、addcolor、addDataなどあります。ボタンがあり、ボタンよりも色があります

この場合、インターフェイスを使用してチェーンする必要があります。メソッドの戻り値の型はインターフェイスであり、すべてのインターフェイスはそのクラスそのメソッドは「this」のみを返します。

これは、インターフェイスのオブジェクトを作成する間、トリックを行います。そして、それを横断してください。ここに例を挙げるのは難しいでしょうが、もしあなたがまだ望むなら、私は例を提供することができます。

任意の更なる詳細は

関連する問題