这是不好的设计吗?

时间:2009-07-10 16:43:36

标签: c# delegates lambda

我有一个控件,它提供了一个选择机制。但是,它选择的项目不适合一般消费,而是必须投影到按日期参数化的不同类型。

除此之外,还有一些控件需要封装相同的信息,更重要的是,即使原始控件的选择发生了变化,也希望保留特定的选择。因此,只是链接方法不起作用,因为原始控件的方法将始终返回其当前选择的投影。

为了解决这个问题,我创建了一个返回闭包的属性,该闭包根据特定的选择执行投影。这样,我可以封装投影并保护正在投影的实际类型,还可以封装特定的集合。这是我所拥有的简化版本。

public class MySelectionControl
{
  public Func<DateTime, IEnumerable<MyProjectedType>> CreateSelectionForDate
  {
    get
    {
       // Take a copy of the selection before creating the lambda so
       // that the source items won't change if the selection does.
       IEnumerable<MyRealType> copyOfSelection = this.realSelection.ToList();
       return weekEnding =>
          copyOfSelection.Select(x => new MyProjectedType(x, weekEnding));
    }
  }
}

然后可以像下面的方法一样调用它:

MySelectionControl control = new MySelectionControl();

// Gives the current selection for a given date.
control.CreateSelectionForDate(DateTime.Today);

// Takes a copy of the selection for later use, regardless of
// whether the original selection changes.
var selectedItemsProjection = control.CreateSelectionForDate;

那么,这种可怕的设计还是巧妙地使用了代表?

2 个答案:

答案 0 :(得分:2)

由于这种安排的目的是提供一个从该上下文中运行的上下文和方法,因此使用它似乎更好:

Closure closure = selectionControl.GetClosure(DateTime.Today);
closure.DateSelection ...

答案 1 :(得分:1)

我认为这很聪明。我唯一要做的就是将你的属性(CreateSelectionForDate)变成一个方法,因为(反正对我来说)会使代码更清晰。