C# 为什么我不能在接口中放置委托?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/612957/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why can't I put a delegate in an interface?
提问by user73936
Why can't I add a delegate to my interface?
为什么我不能向我的界面添加委托?
回答by cgreeno
A Delegateis a typewhich can't be declared in an interface. You might want to either use an event(if appropriate) or declare a delegate outside the interface but in the same namespace.
甲代表是一个类型,其不能在界面中声明。您可能希望使用事件(如果合适)或在接口外部但在同一命名空间中声明委托。
This link may help- When to Use Delegates Instead of Interfaces
此链接可能会有所帮助-何时使用委托而不是接口
回答by Jonathan Allen
A Delegate is just another type, so you don't gain anything by putting it inside the interface.
Delegate 只是另一种类型,因此将它放在接口中并不会获得任何好处。
You shouldn't need to create your own delegates. Most of the time you should just use EventHandler, Func, Predicate, or Action.
您不需要创建自己的委托。大多数情况下,您应该只使用 EventHandler、Func、Predicate 或 Action。
May I ask what your delegate looks like?
请问你的代表长什么样子?
回答by eglasius
You can use any of these:
您可以使用以下任何一种:
public delegate double CustomerDelegate(int test);
public interface ITest
{
EventHandler<EventArgs> MyHandler{get;set;}
CustomerDelegate HandlerWithCustomDelegate { get; set; }
event EventHandler<EventArgs> MyEvent;
}
回答by Guffa
The documentation clearly says that you can define a delegate in an interface:
文档清楚地说明您可以在接口中定义委托:
An interface contains only the signatures of methods, delegates or events.
接口仅包含方法、委托或事件的签名。
MSDN: interface (C# Reference)
However, in the remarks on the same page it says that an interface can contain signatures of methods, properties, indexers and events.
但是,在同一页面的注释中,它说接口可以包含方法、属性、索引器和事件的签名。
If you try to put a delegate in an interface, the compiler says that "interfaces cannot declare types."
如果您尝试在接口中放置委托,编译器会说“接口不能声明类型”。
The Ecma-334 standard (8.9 Interfaces) agrees with the remarks on that page and the compiler.
Ecma-334 标准(8.9 接口)同意该页和编译器上的注释。
回答by Matt
this is a delegate TYPE decalaration...
这是一个委托 TYPE 声明...
public delegate returntype MyDelegateType (params)
this cant be declared in an interface as it is a type declaration
这不能在接口中声明,因为它是类型声明
however using the type declaration above you CAN use a delegate instance
但是使用上面的类型声明,您可以使用委托实例
MyDelegateType MyDelegateInstance ( get; set;)
so delegate instances are OK but delegate type declarations aren't (in an interface)
所以委托实例可以,但委托类型声明不是(在接口中)
回答by swooby
As others have mentioned, you can only define delegates outsideof the interface.
正如其他人所提到的,您只能在界面之外定义委托。
There is little to nothing wrong w/ using delegates.
Personally I think that Func<int, double>
is less desirable than using delegates:
使用委托几乎没有错。我个人认为这Func<int, double>
不如使用委托:
- You cannot name the arguments, so the argument meaning can be ambiguous
It is old news that Events are not thread safe, thus the following code is not ideal:
if (MyFuncEvent != null) { MyFuncEvent(42, 42.42); }
See: http://kristofverbiest.blogspot.com/2006/08/better-way-to-raise-events.html
The safer code is:
MyFuncEventHandler handler = MyFuncEvent; if (handler != null) { handler(42, 42.42); }
You have to duplicate the signature of the event if you want to save it to a variable (or you could use
var
, which I dislike). If you have lots of arguments then this could get very tedious (again, you could always be lazy and usevar
).Func<int, double, string, object, short, string, object> handler = MyFuncEvent; if (handler != null) { handler(42, 42.42, ...); }
- 您无法命名参数,因此参数含义可能不明确
事件不是线程安全的旧闻,因此以下代码并不理想:
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, ...); }
Delegates save you from having to duplicate the signature of the method/event every time you want to assign it to a variable type.
每次您想将方法/事件分配给变量类型时,委托使您不必复制方法/事件的签名。
回答by Paul Williams
An interface method can accept a delegate as a parameter, no issues. (Maybe I'm not seeing the problem?) But if the intention is to specify an outbound call in the interface, use an event.
接口方法可以接受委托作为参数,没有问题。(也许我没有看到问题?)但如果打算在接口中指定出站调用,请使用事件。
There are so many little details, it's a lot easier to just show some code instead of trying to describe it all in prose. (Sorry, even the code sample is a bit bloated...)
有很多小细节,只显示一些代码而不是试图用散文来描述它要容易得多。(抱歉,连代码示例都有些臃肿……)
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();
}
}
}