6

Dart プログラミング言語は、メソッド カスケードをサポートしています。メソッドのカスケードにより、次の Silverlight/WPF 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# でメソッド カスケードをシミュレートまたは近似する方法はありますか?

これが私が思いついた1つのアプローチです。この拡張メソッドを考えると:

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"); })); }));

それが美しいとは言いません。:-) しかし、基本的に流暢なスタイルを適用できます。

4

2 に答える 2

4

流暢なインターフェースを使えば、やりたいことに近づくことができると思います。これにより、メソッドをチェーンして、1つのステートメントでオブジェクトを作成および初期化できます。

あなたはそのようなものを得ることができます:

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

考え方は、メソッドがオブジェクトを返し、別のオブジェクトを初期化できるようにすることです。イニシャライザーのチェーンは、任意のアイテムで「ファイナライザー」メソッド(上記)を呼び出してCreate、元のオブジェクト(上記)を返し、Children他のオブジェクトを追加したり、初期オブジェクトを構成したりすることができます。

したがって、たとえばinは、またはのようなメソッドの束を持つAddListBoxタイプのオブジェクトを返します。この場合、またはなどのメソッドの束を持つ特別なオブジェクト(typeのような)にもなります。各メソッドは、作成する基になるオブジェクトのタイプまたはセットアッププロパティのオブジェクトを作成する責任があります。オブジェクト構造全体を正しく設定して返すメソッドがあります。ListBoxSetupSetWidthAddMouseEnterEventChildrenChildSetupAddListBoxAddTextBoxListBoxTextBoxFluent

このリンクを見てください: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
}
于 2013-01-09T04:27:01.393 に答える
0

以前の回答をサポートしました。同様のタイプのものを作成したので、追加したいものはほとんどありません。

2つのことがあります。1つのクラスで何かをしているということです。フォームを意味し、addcolor、addDataなどがあり、フォームにはボタンがあり、ボタンよりも色がある場合があります

この場合、インターフェイスを使用してチェーンする必要があります。つまり、メソッドの戻り型はインターフェイスになり、すべてのインターフェイスはそのクラスによって実装され、そのメソッドは「this」のみを返します。

インターフェイスのオブジェクトを作成している間、これでうまくいきます。そしてそれを連鎖させます。ここで例を示すのは難しいでしょうが、それでも必要な場合は例を示します。

さらに詳細が必要な場合はお知らせください

于 2013-01-09T08:57:28.403 に答える