【发布时间】:2010-10-11 09:48:09
【问题描述】:
为什么我不能向我的界面添加代理?
【问题讨论】:
标签: c# .net syntax delegates interface
为什么我不能向我的界面添加代理?
【问题讨论】:
标签: c# .net syntax delegates interface
Delegate 是 type,不能在接口中声明。您可能希望使用事件(如果合适)或在接口外部但在同一命名空间中声明委托。
此链接可能会有所帮助-When to Use Delegates Instead of Interfaces
【讨论】:
Delegate 只是另一种类型,因此将其放在界面中不会有任何好处。
您不需要创建自己的委托。大多数情况下,您应该只使用 EventHandler、Func、Predicate 或 Action。
请问你的代表长什么样子?
【讨论】:
您可以使用以下任何一种:
public delegate double CustomerDelegate(int test);
public interface ITest
{
EventHandler<EventArgs> MyHandler{get;set;}
CustomerDelegate HandlerWithCustomDelegate { get; set; }
event EventHandler<EventArgs> MyEvent;
}
【讨论】:
文档清楚地表明您可以在接口中定义委托:
一个接口只包含 方法、委托或 事件。
MSDN: interface (C# Reference)
但是,在同一页的注释中,它说接口可以包含方法、属性、索引器和事件的签名。
如果您尝试将委托放在接口中,编译器会说“接口不能声明类型”。
Ecma-334 标准(8.9 接口)同意该页面和编译器上的注释。
【讨论】:
这是一个委托 TYPE 声明...
public delegate returntype MyDelegateType (params)
this 不能在接口中声明,因为它是类型声明
但是使用上面的类型声明,您可以使用委托实例
MyDelegateType MyDelegateInstance ( get; set;)
所以委托实例是可以的,但委托类型声明不是(在接口中)
【讨论】:
正如其他人所提到的,您只能在接口外部定义委托。
使用委托几乎没有错。
我个人认为Func<int, double> 不如使用委托:
Events 不是线程安全的已经是老消息了,因此下面的代码并不理想:
if (MyFuncEvent != null)
{
MyFuncEvent(42, 42.42);
}
见:http://kristofverbiest.blogspot.com/2006/08/better-way-to-raise-events.html
更安全的代码是:
MyFuncEventHandler handler = MyFuncEvent;
if (handler != null)
{
handler(42, 42.42);
}
如果你想将事件的签名保存到一个变量中,你必须复制它(或者你可以使用我不喜欢的var)。如果您有很多争论,那么这可能会变得非常乏味(同样,您可能总是很懒惰并使用var)。
Func<int, double, string, object, short, string, object> handler = MyFuncEvent;
if (handler != null)
{
handler(42, 42.42, ...);
}
委托使您不必在每次要将其分配给变量类型时复制方法/事件的签名。
【讨论】:
接口方法可以接受委托作为参数,没有问题。 (也许我没有看到问题?)但是如果打算在接口中指定出站调用,请使用事件。
有这么多的小细节,只显示一些代码而不是试图用散文来描述它要容易得多。 (抱歉,连代码示例都有些臃肿了……)
namespace DelegatesAndEvents
{
public class MyEventArgs : EventArgs
{
public string Message { get; set; }
public MyEventArgs(string message) { Message = message; }
}
delegate void TwoWayCallback(string message);
delegate void TwoWayEventHandler(object sender, MyEventArgs eventArgs);
interface ITwoWay
{
void CallThis(TwoWayCallback callback);
void Trigger(string message);
event TwoWayEventHandler TwoWayEvent;
}
class Talkative : ITwoWay
{
public void CallThis(TwoWayCallback callback)
{
callback("Delegate invoked.");
}
public void Trigger(string message)
{
TwoWayEvent.Invoke(this, new MyEventArgs(message));
}
public event TwoWayEventHandler TwoWayEvent;
}
class Program
{
public static void MyCallback(string message)
{
Console.WriteLine(message);
}
public static void OnMyEvent(object sender, MyEventArgs eventArgs)
{
Console.WriteLine(eventArgs.Message);
}
static void Main(string[] args)
{
Talkative talkative = new Talkative();
talkative.CallThis(MyCallback);
talkative.TwoWayEvent += new TwoWayEventHandler(OnMyEvent);
talkative.Trigger("Event fired with this message.");
Console.ReadKey();
}
}
}
【讨论】: