C#-有人能告诉我为什么以及在哪里使用代理吗?
我想我理解C#中委托作为方法指针的概念,但是我找不到任何好的例子来说明在哪里使用它们是一个好主意。哪些示例对于学员而言明显更优雅/更好,或者无法使用其他方法解决 我主要使用用于简单异步编程的。正在使用委托开始启动方法。。。如果你想开火然后忘记,这个方法真的很简单C#-有人能告诉我为什么以及在哪里使用代理吗?,c#,delegates,C#,Delegates,我想我理解C#中委托作为方法指针的概念,但是我找不到任何好的例子来说明在哪里使用它们是一个好主意。哪些示例对于学员而言明显更优雅/更好,或者无法使用其他方法解决 我主要使用用于简单异步编程的。正在使用委托开始启动方法。。。如果你想开火然后忘记,这个方法真的很简单 当接口不可用时,委托也可以像接口一样使用。例如,从COM类、外部.Net类等调用方法。delgates将解决其他方法无法解决的问题,但它们提供了一个更优雅的解决方案 对于委托,只要具有所需参数,就可以使用任何函数 另一种方法通常是在程序
当接口不可用时,委托也可以像接口一样使用。例如,从COM类、外部.Net类等调用方法。delgates将解决其他方法无法解决的问题,但它们提供了一个更优雅的解决方案 对于委托,只要具有所需参数,就可以使用任何函数
另一种方法通常是在程序中使用一种定制的事件系统,为.NET 1.0代理中的bug创建额外的工作和更多的区域:
this.myButton.Click += new EventHandler(this.MyMethod);
this.myOtherButton.Click += delegate {
var res = PerformSomeAction();
if(res > 5)
PerformSomeOtherAction();
};
.NET 2.0代表:
this.myButton.Click += new EventHandler(this.MyMethod);
this.myOtherButton.Click += delegate {
var res = PerformSomeAction();
if(res > 5)
PerformSomeOtherAction();
};
它们似乎很有用。那么:
new Thread(new ThreadStart(delegate {
// do some worker-thread processing
})).Start();
事件是最明显的例子。比较观察者模式在Java(接口)和C#(委托)中的实现方式
此外,许多新的C#3功能(例如lambda表达式)都基于委托,并进一步简化了它们的使用。例如在多线程应用程序中。如果希望多个线程使用某些控件,则应使用委托。抱歉,代码是VisualBasic 首先声明一个委托
Private Delegate Sub ButtonInvoke(ByVal enabled As Boolean)
编写一个函数,从多个线程启用/禁用按钮
Private Sub enable_button(ByVal enabled As Boolean)
If Me.ButtonConnect.InvokeRequired Then
Dim del As New ButtonInvoke(AddressOf enable_button)
Me.ButtonConnect.Invoke(del, New Object() {enabled})
Else
ButtonConnect.Enabled = enabled
End If
End Sub
我一直在LINQ中使用它们,尤其是lambda表达式,以提供一个函数来计算条件或返回选择。还可以使用它们提供一个功能,用于比较两个项目进行排序。后者对于默认排序可能合适也可能不合适的泛型集合非常重要
var query = collection.Where( c => c.Kind == ChosenKind )
.Select( c => new { Name = c.Name, Value = c.Value } )
.OrderBy( (a,b) => a.Name.CompareTo( b.Name ) );
委托的好处之一是异步执行
当您异步调用一个方法时,您不知道它将在何时完成执行,因此您需要向该方法传递一个委托,该委托指向在第一个方法完成执行时将调用的另一个方法。在第二种方法中,您可以编写一些代码,通知您执行已完成。其他一些关于异步世界的注释。。。但我还是要评论一下,因为我最喜欢的“味道”是这样做的:
ThreadPool.QueueUserWorkItem(delegate
{
// This code will run on it's own thread!
});
此外,委托的一个重要原因是“回调”。假设我做了一些功能(异步),您希望我调用一些方法(比如“AlertWhenDone”)。。。您可以按如下方式向方法传递“委托”:
TimmysSpecialClass.DoSomethingCool(this.AlertWhenDone);
委托在事件中的角色(如果您使用过winforms或asp.net,您可能会很熟悉)之外,还有助于使类更灵活(例如在LINQ中使用它们的方式) “发现”事物的灵活性相当普遍。你有很多东西,你想提供一种找到东西的方法。现在,您可以允许调用者提供算法,以便他们可以按照自己认为合适的方式搜索您的集合,而不是猜测某人可能想要查找的每种方式 下面是一个简单的代码示例:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Delegates
{
class Program
{
static void Main(string[] args)
{
Collection coll = new Collection(5);
coll[0] = "This";
coll[1] = "is";
coll[2] = "a";
coll[3] = "test";
var result = coll.Find(x => x == "is");
Console.WriteLine(result);
result = coll.Find(x => x.StartsWith("te"));
Console.WriteLine(result);
}
}
public class Collection
{
string[] _Items;
public delegate bool FindDelegate(string FindParam);
public Collection(int Size)
{
_Items = new string[Size];
}
public string this[int i]
{
get { return _Items[i]; }
set { _Items[i] = value; }
}
public string Find(FindDelegate findDelegate)
{
foreach (string s in _Items)
{
if (findDelegate(s))
return s;
}
return null;
}
}
}
输出
是
测试你所说的代表到底是什么意思?以下是它们的两种使用方式:
void Foo(Func<int, string> f) {
//do stuff
string s = f(42);
// do more stuff
}
void Foo(函数f){
//做事
字符串s=f(42);
//多做事
}
及
void Bar(){
Func f=委托(i){返回i.ToString();}
//做事
字符串s=f(42);
//多做事
}
第二种方法的要点是,您可以动态地以委托的形式声明新函数。这在很大程度上可以被lambda表达式所取代,并且在任何时候,只要有一小段逻辑想要1)传递给另一个函数,或者2)只是重复执行,它都很有用。LINQ就是一个很好的例子。每个LINQ函数都将lambda表达式作为其参数,指定行为。例如,如果您有一个列表l
,那么l.Select(x=>(x.ToString())
将对列表中的每个元素调用ToString()。我编写的lambda表达式作为委托实现
第一种情况显示了如何实现Select。您可以将委托作为参数,然后在需要时调用它。这允许调用方自定义函数的行为。使用Select()再举一个例子,函数本身保证您传递给它的委托将在列表中的每个元素上被调用,并返回每个元素的输出。该委托的实际作用取决于您。这使它成为一个非常灵活和通用的函数
当然,它们也用于订阅事件。简言之,委托允许您引用函数,在函数调用中使用它们作为参数,将它们分配给变量以及您喜欢做的任何事情。从技术上讲,委托是一种引用类型,用于封装具有特定签名和返回类型的方法在处理对数据库的外部调用时,使用委托是否有优势 例如,您可以编写以下代码:
static void Main(string[] args) {
DatabaseCode("test");
}
public void DatabaseCode(string arg) {
.... code here ...
}
在代码B中需要改进:
static void Main(string[] args) {
DatabaseCodeDelegate slave = DatabaseCode;
slave ("test");
}
public void DatabaseCode(string arg) {
.... code here ...
}
public delegate void DatabaseCodeDelegate(string arg);
这似乎是主观的,但这是一个存在强烈冲突的观点的领域?天哪,我差不多一年前就提出了这个问题,现在很难想象在代表/lambda表达之前的生活!我不得不说,这里的答案仍然是网络上最好的例子。这就是SO的力量。这简直太棒了理解