为什么我不能在我的界面中添加委托?
答案 0 :(得分:33)
您可以使用以下任何一种:
public delegate double CustomerDelegate(int test);
public interface ITest
{
EventHandler<EventArgs> MyHandler{get;set;}
CustomerDelegate HandlerWithCustomDelegate { get; set; }
event EventHandler<EventArgs> MyEvent;
}
答案 1 :(得分:24)
委托只是另一种类型,所以你不能通过把它放在界面中来获得任何东西。
您不需要创建自己的代理。大多数情况下,您应该只使用EventHandler,Func,Predicate或Action。
我可以问你的代表是什么样的吗?
答案 2 :(得分:7)
Delegate是type,无法在界面中声明。您可能希望使用事件(如果适用)或在接口外部但在同一名称空间中声明委托。
此链接可能会有所帮助 - When to Use Delegates Instead of Interfaces
答案 3 :(得分:6)
这是委托TYPE decalaration ...
public delegate returntype MyDelegateType (params)
这不能在接口中声明,因为它是一个类型声明
但是使用上面的类型声明,您可以使用委托实例
MyDelegateType MyDelegateInstance ( get; set;)
所以委托实例没问题,但代理类型声明不是(在界面中)
答案 4 :(得分:4)
文档明确指出您可以在界面中定义委托:
界面仅包含 方法,代表或的签名 事件
MSDN: interface (C# Reference)
但是,在同一页面上的备注中,它表示接口可以包含方法,属性,索引器和事件的签名。
如果您尝试将委托放在接口中,编译器会说“接口不能声明类型。”
Ecma-334标准(8.9接口)同意该页面和编译器的评论。
答案 5 :(得分:1)
正如其他人所提到的,您只能在界面之外定义代理。
使用代表几乎没有错。
我个人认为Func<int, double>
不如使用代表那么可取:
事件不是线程安全的老消息,因此以下代码并不理想:
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, ...);
}
代表可以避免每次要将其分配给变量类型时复制方法/事件的签名。
答案 6 :(得分:0)
接口方法可以接受委托作为参数,没有问题。 (也许我没有看到问题?)但如果打算在界面中指定出站呼叫,请使用事件。
有很多细节,只是展示一些代码而不是试图在散文中描述它们要容易得多。 (对不起,即使代码示例有点臃肿......)
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();
}
}
}