【问题标题】:Simulating method cascades in C#在 C# 中模拟方法级联
【发布时间】:2013-01-09 04:16:11
【问题描述】:

Dart 编程语言支持method cascades。方法级联将允许以下 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# 中模拟或近似方法级联?

这是我想出的一种方法。鉴于此扩展方法:

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

我不会说那很漂亮。 :-) 但它确实可以应用流畅的样式。

【问题讨论】:

  • 你不是在找Object initializers吗?
  • @SimonWhitehead 对象初始化器仅适用于属性。该示例包括事件和方法调用。
  • 我认为你所拥有的是尽可能接近。老实说,我不认为它比你的 Dart 例子丑得多。
  • @juharr 确实.. 傻我! :)
  • 您可以随时切换到 VB.NET 并使用 With 块...

标签: c# dart method-cascades


【解决方案1】:

我认为您可以通过使用流畅的界面来接近您想要实现的目标。它将允许您在一个语句中链接方法来创建和初始化对象。

你可以得到类似的东西:

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

这个想法是一个方法返回一个允许初始化另一个对象的对象。初始化器链可以在任何项目上调用“终结器”方法(@​​987654323@ 以上),该方法返回原始对象(Children 以上)以继续添加其他对象或配置初始对象。

例如,在AddListBox 中返回一个ListBoxSetup 类型的对象,它有一堆方法,如SetWidthAddMouseEnterEvent。在这种情况下,Children 也将是一个特殊对象(如ChildSetup 类型),它具有一系列方法,例如AddListBoxAddTextBox。每个方法都负责创建ListBoxTextBox 类型的对象或设置要创建的基础对象的属性。 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
}

【讨论】:

    【解决方案2】:

    我支持以前的答案。我喜欢添加的东西很少,因为我已经创建了类似类型的东西。

    有两件事,要么你有一个班级做事。表示表单,有 addcolor、addData 等,可能是表单有按钮,而按钮有颜色

    现在在这种情况下,您需要使用接口进行链接,这意味着方法返回类型将是接口,并且所有接口都由该类实现,并且该方法仅返回“this”。

    当您创建接口对象时,这将起到作用。然后把它串起来。这里很难举例,但如果你还想我可以提供例子。

    如果需要任何进一步的细节,请告诉我

    【讨论】:

      猜你喜欢
      • 2013-10-18
      • 2010-11-07
      • 1970-01-01
      • 1970-01-01
      • 2016-09-28
      • 2011-12-19
      • 2023-02-20
      • 1970-01-01
      相关资源
      最近更新 更多