在c#中模拟方法级联
本文关键字:方法 级联 模拟 | 更新日期: 2023-09-27 17:51:07
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#中的方法级联?
这是我想到的一个方法。给定这个扩展方法:
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"); })); }));
我不认为那很漂亮。
我认为使用流畅的界面可以接近你想要达到的效果。它允许你在一条语句中链接方法来创建和初始化对象。
你可以得到这样的东西:
Fluent fluent = new Fluent();
var panel = fluent.CreateControlPanel().Children()
.AddListBox().SetWidth(200).AddMouseEnterEvent((s, e) => { }).Create()
.AddTextBox().SetText("Foo").Create()
.GetControlPanel();
方法返回的对象允许初始化另一个对象。初始化器链可以在任何项上调用一个"终结器"方法(Create
以上),该方法返回原始对象(Children
以上),以继续添加其他对象或配置初始对象。
例如,在AddListBox
中返回一个类型为ListBoxSetup
的对象,它有一堆方法,如SetWidth
或AddMouseEnterEvent
。在这种情况下,Children
也将是一个特殊的对象(像ChildSetup
类型),它有一堆方法,如AddListBox
或AddTextBox
。每个方法都负责创建类型为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
}
我支持前面的答案。我喜欢添加一些东西,因为我已经创建了类似类型的东西。
有两件事,要么你有一个类做事情。意思是表单,有addcolor, addData等也可能是表单有按钮而按钮有颜色
现在在这种情况下,你需要链式使用接口,这意味着方法返回类型将是接口,所有的接口都是由那个类实现的,并且方法只返回"this"。
当您创建object of interface时,就可以了。然后把它链起来。在这里举例比较困难,但如果你仍然需要,我可以提供一个例子。
如果需要进一步的细节请告诉我