鉴于“大多数”开发人员是业务应用程序开发人员,我们最喜欢的编程语言的功能将用于我们正在使用它们的上下文中。
作为C#/ ASP.NET应用程序开发人员,我倾向于在处理UI事件时仅使用委托。事实上(这是我缺乏经验的一部分),我甚至不知道除了使用代表的事件之外的好的上下文!这是非常可怕的;但是我知道还有其他开发人员在同一条船上。
NB :答案应该与.NET 2.0有关。 .NET 3.0将代理完全带到了不同的级别,这可能是一个单独的问题。
除了事件之外,委托有多大用处,以及哪些业务应用程序上下文最有用?
更新:Jarrod Dixon helpfully linked到MSDN文档regarding delegate usage,我必须承认我的favorite Design Patterns Book没有提请代表参加所有,所以除了用于UI事件之外,我还没有真正看到它们的使用。要扩展这个问题(只是一点点!),您可以为业务应用程序(或者实际上,任何必须处理相关问题的应用程序)提供哪些示例,以便更容易地消化有关该主题的MSDN文档?
答案 0 :(得分:4)
我认为这个问题反映了皮肤猫的许多方法。我发现委托(和lambdas)几乎和“for”循环一样基本。
这是我最近使用代理的一个上下文(为了演示目的而更改了格式和名称:)
protected T[] SortLines<T>(Func<T> createLine, IEnumerable<T> unsorted)
where T : LineType
{
Func<IEnumerable<T>, IEnumerable<T>> sorter = (lines => lines);
switch (settings.OrderSort)
{
case OrderSort.ByA:
sorter = (lines => lines.OrderBy(x => x.A)); break;
case OrderSort.ByB:
sorter = (lines => lines.OrderBy(x => x.B)); break;
// and so on... a couple cases have several levels of ordering
}
bool requiresSplit = // a complicated condition
if (requiresSplit)
{
var positives = unsorted.Where(x => x.Qty >= 0);
var negatives = unsorted.Where(x => x.Qty < 0);
return sorter(negatives).Concat(
new T[] { createLine.Invoke() }).Concat(
sorter(positives)).ToArray();
}
else
return sorter(unsorted).ToArray();
}
因此,这会根据某些条件对一组项目进行排序,然后将整个列表排序,或者将其分成两部分,分别对两半进行排序,并在它们之间放置一个分隔符。祝你好运,如果你不能表达“一种分类方式”的概念,这就是代表所要求的。
编辑:我猜Concat和OrderBy是3.0特定的,但这仍然是基本的想法。
答案 1 :(得分:2)
除了GUI ......
答案 2 :(得分:2)
据我所知,.NET委托本质上是一个单方法接口的实现,没有所有的类声明hoopla。我希望我们亲自在Java中使用它们。想想比较器类:
class MyComparator<Circle> extends Comparator<Circle> {
public int compare(Circle a, Circle b) {
return a.radius - b.radius;
}
}
任何地方这种模式都很有用,代理可能会有用。
我希望我是对的,但如果我错了,请继续投票。自从我看到任何C#以来已经太久了:)
答案 3 :(得分:2)
代表的另一个重要用途是作为状态机。如果您的程序逻辑包含重复的if ... then语句来控制它所处的状态,或者如果您使用复杂的开关块,则可以轻松地使用它们来复制State模式。
enum State {
Loading,
Processing,
Waiting,
Invalid
}
delegate void StateFunc();
public class StateMachine {
StateFunc[] funcs; // These would be initialized through a constructor or mutator
State curState;
public void SwitchState(State state) {
curState = state;
}
public void RunState() {
funcs[curState]();
}
}
我的2.0委托语法可能生锈,但这是状态调度程序的一个非常简单的例子。还要记住,C#中的委托可以执行多个函数,允许你拥有一个状态机,每个RunState()执行任意多个函数。
答案 4 :(得分:1)
当您执行任何异步操作(例如进行Web服务调用)时,您可以使用委托,这样当调用返回时,您可以启动委托调用以便目标处理。
答案 5 :(得分:1)
我多年来看到的一种常见模式(使用各种语言)是“冻结”决定将逻辑从循环中移出到设置中的结果。在伪代码中(因为该技术因语言而异):
some_condition = setup_logic
...
while (not terminated) {
data = obtain_data
if (some_condition)
process_one (data)
else
process_two (data)
}
关键是如果some_condition
没有根据循环中的任何内容而改变,那么反复测试它确实没有任何好处。代表/关闭/等。允许将上述内容替换为:
some_condition = setup_logic
if (some_condition)
selected_process = process_one
else
selected_process = process_two
...
while (not terminated) {
data = obtain_data
selected_process (data)
}
(当然,Real Functional Programmer会将设置编写为:
selected_process = if (some_condition) process_one else process_two
- )
这很好地概括了多个替代方案(而不仅仅是两个)。关键的想法是提前决定在未来一点(或多点)采取什么行动,然后记住所选择的行动而不是值,决定是基于
答案 6 :(得分:1)
当你开始将它们视为功能构造时,代表变得非常强大
.Net 2.0包括对匿名委托的支持,它构成了Linq扩展的一些功能概念的核心。匿名委托的语法比Lambda提供的要大一些,但2.0中有很多核心功能模式。
在列表通用类型中,您可以使用以下项目:
来自List特定项目的Appart,当正确处理使用匿名委托上下文时,您可以实现Closure之类的结构。或者,在更实际的层面上做类似的事情:
ILog logger = new Logger();
MyItemICareAbout.Changed += delegate(myItem) { logger.Log(myItem.CurrentValue); };
它只是有效。
还有DynamicMethod的东西,它允许你定义IL的位(使用Reflection.Emit),并将它们编译为委托。这为您提供了一种替代纯映射的替代方法,例如映射层和数据访问代码。
代理实际上是一个允许您将可执行代码表示为数据的构造。一旦你了解了这意味着什么,就可以做很多事情。与3.5相比,2.0中这些结构的支持是基本的,但仍然存在,并且仍然相当强大。
答案 7 :(得分:1)
代表通常用于事件调度,但这只是因为它们很方便。委托对任何类型的方法调用都很有用。它们还具有许多其他功能,例如异步调用的功能。
委托的基本原因是提供Closure,或者能够调用函数及其状态,这通常是一个对象实例。