我很困惑,代表的实际角色是什么?
在我的采访中我多次被问到这个问题,但我不认为采访者对我的回答感到满意。
有人能用一个实际的例子用一句话告诉我最佳定义吗?
答案 0 :(得分:157)
我喜欢将委托视为“指向函数的指针”。这可以追溯到C天,但这个想法仍然存在。
这个想法是你需要能够调用一段代码,但是你要调用的那段代码直到运行时才知道。所以你为此目的使用“委托”。代表们可以为事件处理程序等事务派上用场,例如,根据不同的事件,您可以根据不同的事件执行不同的操作。
Here's您可以查看C#的参考资料:
例如,在C#中,假设我们有一个我们想要做的计算,我们想要使用一种我们在运行时才知道的不同计算方法。所以我们可能会有几个这样的计算方法:
public static double CalcTotalMethod1(double amt)
{
return amt * .014;
}
public static double CalcTotalMethod2(double amt)
{
return amt * .056 + 42.43;
}
我们可以声明这样的委托签名:
public delegate double calcTotalDelegate(double amt);
然后我们可以声明一个将委托作为参数的方法:
public static double CalcMyTotal(double amt, calcTotalDelegate calcTotal)
{
return calcTotal(amt);
}
我们可以调用CalcMyTotal
方法传递我们想要使用的委托方法。
double tot1 = CalcMyTotal(100.34, CalcTotalMethod1);
double tot2 = CalcMyTotal(100.34, CalcTotalMethod2);
Console.WriteLine(tot1);
Console.WriteLine(tot2);
答案 1 :(得分:18)
委托只是一个函数指针 只需让您分配您希望运行代理的方法即可。 然后在代码中你可以通过Invoke调用该方法。
要演示的一些代码(从内存写入,因此语法可能会关闭)
delegate void delMyDelegate(object o);
private void MethodToExecute1(object o)
{
// do something with object
}
private void MethodToExecute2(object o)
{
// do something else with object
}
private void DoSomethingToList(delMyDelegate methodToRun)
{
foreach(object o in myList)
methodToRun.Invoke(o);
}
public void ApplyMethodsToList()
{
DoSomethingToList(MethodToExecute1);
DoSomethingToList(MethodToExecute2);
}
答案 2 :(得分:15)
问代表什么是什么? A 当对象收到请求时,对象可以自己处理请求,也可以将请求传递给第二个对象来完成工作。如果对象决定打开请求,则表示该对象已将处理请求的责任转发给第二个对象。
或者,作为一个简单的伪示例:某事件向object1发送请求。然后object1将请求及其自身转发给object2 - 委托。 object2处理请求并完成一些工作。 (注意:上面的链接给出了很好的例子)
答案 3 :(得分:4)
将委托视为关于Command模式的简化实现。
答案 4 :(得分:4)
委托是可以引用方法的对象。因此,当我们创建委托时,我们正在创建一个可以保存对方法的引用的对象。此外,可以通过该参考调用该方法。因此,委托可以调用它引用的方法。 委托的主要优点是它允许我们指定对方法的调用,但实际调用的方法是在运行时确定的,而不是在编译时确定的。
简单代表
Declaration of delegate:
delegate-modifier delegate return-type delegate-name(parameters)
Implementation of delegate:
Delegate-name delegate-object=new Delegate-name(method of class)
答案 5 :(得分:2)
这里我将解释代表,多播代表及其用法。 Delegate是一种在对象中保存方法引用的类型。它也被称为类型安全函数指针。我们可以说委托是一种定义方法签名的类型。
实例化委托时,可以将其实例与具有兼容签名的任何方法相关联。您可以通过委托实例调用(或调用)该方法。 委托用于将方法作为参数传递给其他方法。 事件处理程序只不过是通过委托调用的方法。 使用代表的优点是, 封装来自调用者的方法调用 有效使用委托可以提高应用程序的性能 用于异步调用方法。 代表的一些属性是
Delegates are like C++ function pointers but are type safe.
Delegates allow methods to be passed as parameters.
Delegates can be used to define callback methods.
Delegates can be chained together; for example, multiple methods can be called on a single event.
Methods do not have to match the delegate signature exactly.
public delegate type_of_delegate delegate_name()//声明
You can use delegates without parameters or with parameter list
If you are referring to the method with some data type then the delegate which you are declaring should be in the same format. This is why it is referred to as type safe function pointer. Here I am giving an example with String.
以下示例显示了委托操作:
namespace MyDelegate
{
class Program
{
private delegate void Show(string s);
// Create a method for a delegate.
public static void MyDelegateMethod(string me
ssage)
{
System.Console.WriteLine(message);
}
static void Main(string[] args)
{
Show p = MyDelegateMethod;
p("My Delegate");
p.Invoke("My Delegate");
System.Console.ReadLine();
}
}
}
什么是多播代理?
它是一个委托,它拥有多个方法的引用。多播委托必须仅包含返回void的方法,否则会出现运行时异常。
delegate void MyMulticastDelegate(int i, string s);
Class Class2
{
static void MyFirstDelegateMethod(int i, string s)
{
Console.WriteLine("My First Method");
}
static void MySecondDelegateMethod(int i, string s)
{
Console.WriteLine("My Second Method");
}
static void Main(string[] args)
{
MyMulticastDelegate Method= new MyMulticastDelegate(MyFirstDelegateMethod);
Method+= new MyMulticastDelegate (MySecondDelegateMethod);
Method(1,"Hi"); // Calling 2 Methodscalled
Method-= new MyMulticastDelegate (MyFirstDelegateMethod);
Method(2,"Hi"); //Only 2nd Method calling
}
}
此处使用+ =运算符添加Delegate,并使用 - =运算符删除。
委托类型派生自.NET Framework中的Delegate类。委托类型是密封的 - 它们无法派生。 因为实例化的委托是一个对象,所以它可以作为参数传递,也可以分配给属性。这允许方法接受委托作为参数,并在稍后调用委托。这称为异步回调。
答案 6 :(得分:1)
可以在Google Collections Forwarding Classes(也是Decorator模式)中找到代表模式的精彩解释和实际实现。
答案 7 :(得分:1)
在事件通信中,发件人不知道哪个对象将处理该事件。 Delegate是持有方法引用的类型。 Delegate具有签名并且保持对与其签名匹配的方法的引用 所以Delegate就像类型安全函数指针。
button1.Click + = new System.EventHandler(button1_Click) System.EventHandler在此声明为委托 在.net Events中使用Delegate的概念(如Button Click)
当您不知道在运行时调用哪个代码时,将使用Delegate 所以当时Delegate用于处理事件
http://msdn.microsoft.com/en-us/library/ms173171(v=vs.80).aspx
答案 8 :(得分:1)
代表主要用于事件。
需要:
您不希望在运行程序时执行一段代码。 运行程序后,您希望在发生事件时执行该段代码。
示例:
这就是他们所说的,你不知道在编译时会调用哪种方法。你只知道它在运行时点击按钮。
没有委托,就不可能进行用户界面编程。因为只要用户点击按钮,输入文本框,选择下拉列表项等等,就会执行代码....
答案 9 :(得分:1)
委托对象 是一个对象,当该对象发生某些事情时,另一个对象会参考。对于 例如,如果你的车发生了什么事,你的维修人员就是你的代表。你去找你的修理工并让他为你修车(虽然有些人喜欢自己修车,在这种情况下,他们是他们自己的汽车代表)。
答案 10 :(得分:1)
委托是一个表示函数指针的对象。但是,它不是普通的函数指针:
1)面向对象
2)类型是否安全,即它只能指向一个方法而你无法读取它所指向的原始内存地址
3)强类型。它只能指向与其签名匹配的方法。
4)可以同时指向多种方法。
答案 11 :(得分:0)
委托是委派任务的东西。委派的主要目的是解耦代码并允许更大的灵活性和重用。
在编程中,特别是面向对象的编程中,这意味着当调用方法来完成某些工作时,它会将工作传递给它引用的另一个对象的方法。只要对象符合预定义的一组方法,引用就可以指向我们希望的任何对象。我们称之为“编程到接口”(而不是编程到具体的类实现)。接口基本上是通用模板,没有实现;它只是指一个食谱,一组方法,前置条件和后置条件(规则)。
简单示例:
SomeInterface
{
public void doSomething();
}
SomeImplementation implements SomeInterface
{
public void doSomething()
{
System.err.println("Was it good for you?");
}
}
SomeCaller
{
public void doIt(SomeInterface someInterface)
{
someInterface.doSomething();
}
}
现在你看到我可以随时使用我想要的任何实现,而无需更改SomeCaller中的代码,因为传递doIt()
的类型不是具体的,而是抽象的,因为它是一个接口。在Java世界中,这通常表现在服务范例中,在这种范例中,您调用服务(通过特定接口将自身作为服务广告的对象),然后服务调用代理来帮助它完成工作。服务的方法被命名为粗粒度任务(makePayment(),createNewUser()等),而在内部它通过委托来执行很多工作,代理的类型是接口而不是具体的实现。 / p>
SomeService
{
SomeInterface someImplementation = ... // assign here
SomeOtherInterface someOtherImplementation = ... // okay, let's add a second
public void doSomeWork()
{
someImplementation.doSomething();
someOtherImplementation.doSomethingElse();
}
}
(N.B。:如何分配实现超出了此线程的范围。查找控制和依赖注入的反转。)
答案 12 :(得分:-2)
虽然不是真正的“函数指针”,但委托可能看起来像是像PHP一样的动态语言:
$func = 'foo';
$func();
function foo() {
print 'foo';
}
或在JavaScript中,您可以执行以下操作:
var func = function(){ alert('foo!'); }
func();