C# 从函数返回事件
从函数返回事件的语法是什么?(不调用事件,而是返回事件以便将其绑定到函数) 我有一个容器类,其中包含一个字典,每个成员都有一个事件 目的是能够写出这样的东西:C# 从函数返回事件,c#,events,C#,Events,从函数返回事件的语法是什么?(不调用事件,而是返回事件以便将其绑定到函数) 我有一个容器类,其中包含一个字典,每个成员都有一个事件 目的是能够写出这样的东西: Container c = new Container(); c.CreateEventForKey("a"); // Create the member in the dictionary c.EventForKey("a") += some_function; // Bind some_function to
Container c = new Container();
c.CreateEventForKey("a"); // Create the member in the dictionary
c.EventForKey("a") += some_function; // Bind some_function to the event in the "a" member
c.OnEventForKey("a","b"); // Calls some_function with argument "b"
public class Container {
public class Member {
public event Action<string> AnEvent;
public void OnEvent( string v ) { if(AnEvent!=null) { AnEvent(v); } }
}
protected Dictionary<string,Member> members;
// This seems to work OK.
public void OnEventForKey(string k, string v) {
if ( members.ContainsKey(k) ) { members[k].OnEvent(v); }
else { /* report error */ }
}
// Can't get this to compile.
public event Action<string> EventForKey(string k ) {
if ( members.ContainsKey(k) ) { return members[k].AnEvent; }
else { /* report error */ }
}
}
容器类如下所示:
Container c = new Container();
c.CreateEventForKey("a"); // Create the member in the dictionary
c.EventForKey("a") += some_function; // Bind some_function to the event in the "a" member
c.OnEventForKey("a","b"); // Calls some_function with argument "b"
public class Container {
public class Member {
public event Action<string> AnEvent;
public void OnEvent( string v ) { if(AnEvent!=null) { AnEvent(v); } }
}
protected Dictionary<string,Member> members;
// This seems to work OK.
public void OnEventForKey(string k, string v) {
if ( members.ContainsKey(k) ) { members[k].OnEvent(v); }
else { /* report error */ }
}
// Can't get this to compile.
public event Action<string> EventForKey(string k ) {
if ( members.ContainsKey(k) ) { return members[k].AnEvent; }
else { /* report error */ }
}
}
公共类容器{
公共班级成员{
公共事件行动事件;
public void OnEvent(字符串v){if(AnEvent!=null){AnEvent(v);}
}
受保护的词典成员;
//这似乎行得通。
public void oneventforky(字符串k、字符串v){
if(members.ContainsKey(k)){members[k].OnEvent(v);}
else{/*报告错误*/}
}
//无法将其编译。
公共事件操作EventForKey(字符串k){
if(members.ContainsKey(k)){返回成员[k].AnEvent;}
else{/*报告错误*/}
}
}
我如何定义EventForKey
,使其符合我的期望
从函数返回事件的语法是什么
你不能,很容易。像属性一样的事件本身并不是第一类的“对象”;他们是一个班级的成员。这里实际上没有一个类成员——你只是想把委托保存在字典中
<>你可以创建你自己的“事件类”容器,但是最好考虑其他设计,例如
c.Subscribe("a", SomeFunction);
c.OnEventForKey("a");
您可能想从中获得灵感。为什么不直接返回会员并订阅其活动
public IMember MemberForKey(string key) // return IMember
{
if (!members.ContainsKey(key))
throw new Exception();
return members[key];
}
然后订阅:
Container c = new Container();
c.CreateEventForKey("a");
c.MemberForKey("a").AnEvent += some_function;
c.OnEventForKey("a", "b");
但是在Member
类中有publicOnEvent
方法。为了禁止客户端引发事件,您可以创建只显示事件的接口。只需通过成员
类实现此接口:
public interface IMember
{
event Action<string> AnEvent;
}
事件的目的是只为客户端提供两个操作—添加和删除处理程序。委托本身对客户端是隐藏的。您可以将其公开:
public Action<string> _action;
public Action\u Action;
但在这种情况下,任何客户端都可以调用它
更新:如果您想使用Subscribe/Remove语法,只需使用字典和处理程序:
public class Container
{
private Dictionary<string, Action<string>> handlers =
new Dictionary<string, Action<string>>();
public void CreateEventForKey(string key)
{
// with empty handler added you can avoid null check
handlers.Add(key, (value) => { });
}
public void OnEventForKey(string key, string value)
{
if (!handlers.ContainsKey(key))
throw new Exception();
handlers[key](value);
}
public void Subscribe(string key, Action<string> handler)
{
if (!handlers.ContainsKey(key))
throw new Exception();
handlers[key] += handler;
}
}
公共类容器
{
专用字典处理程序=
新字典();
public void CreateEventForKey(字符串键)
{
//添加空处理程序后,可以避免空检查
Add(key,(value)=>{});
}
public void OneEventWorkey(字符串键、字符串值)
{
如果(!handlers.ContainsKey(键))
抛出新异常();
处理程序[键](值);
}
public void Subscribe(字符串键、操作处理程序)
{
如果(!handlers.ContainsKey(键))
抛出新异常();
处理程序[键]+=处理程序;
}
}
以下是完整的工作示例:
class Program
{
static void Main(string[] args)
{
Container c = new Container();
c.CreateEventForKey("a"); // Create the member in the dictionary
c.EventForKey("a").Add(str => Console.WriteLine(str));
c.EventForKey("a").Add(str => Console.WriteLine(str.ToUpper()));
c.OnEventForKey("a", "baa baa black sheep");
Console.ReadLine();
}
}
public class Container
{
public class Member
{
public List<Action<string>> AnEvent = new List<Action<string>>();
public void OnEvent(string v)
{
if (AnEvent != null)
{
this.AnEvent.ForEach(action => action(v));
}
}
public void AddEvent(Action<string> action)
{
this.AnEvent.Add(action);
}
}
protected Dictionary<string, Member> members = new Dictionary<string,Member>();
public void CreateEventForKey(string key)
{
this.members[key] = new Member();
}
// This seems to work OK.
public void OnEventForKey(string k, string v)
{
if (members.ContainsKey(k)) { members[k].OnEvent(v); }
else { /* report error */ }
}
public List<Action<string>> EventForKey(string k)
{
if (members.ContainsKey(k)) { return members[k].AnEvent; }
else { throw new KeyNotFoundException(); }
}
}
类程序
{
静态void Main(字符串[]参数)
{
容器c=新容器();
c、 CreateEventForKey(“a”);//在字典中创建成员
c、 EventForKey(“a”).Add(str=>Console.WriteLine(str));
c、 EventForKey(“a”).Add(str=>Console.WriteLine(str.ToUpper());
c、 Oneventforky(“a”、“baa baa害群之马”);
Console.ReadLine();
}
}
公营货柜
{
公共班级成员
{
public List AnEvent=新列表();
公共void OnEvent(字符串v)
{
if(AnEvent!=null)
{
this.AnEvent.ForEach(action=>action(v));
}
}
公共无效事件(行动)
{
this.AnEvent.Add(action);
}
}
受保护的字典成员=新字典();
public void CreateEventForKey(字符串键)
{
this.members[key]=新成员();
}
//这似乎行得通。
public void oneventforky(字符串k、字符串v)
{
if(members.ContainsKey(k)){members[k].OnEvent(v);}
else{/*报告错误*/}
}
公共列表EventForKey(字符串k)
{
if(members.ContainsKey(k)){返回成员[k].AnEvent;}
else{抛出新的KeyNotFoundException();}
}
}
不同之处在于,使用委托列表的行为类似于事件。我认为您不能返回事件,但可以返回可以绑定到事件的委托。这就是你的意思吗?我想你只需要从一个事件的声明中删除event关键字,以及从EventForKey的返回类型中删除它。@IanNewson-我遇到问题的关键部分是
c.EventForKey(“a”)+=some\u函数代码>。我宁愿写这篇文章,也不愿写那些繁琐的c.members[“a”].AnEvent+=some_函数(因为我可以在第一个版本中添加错误检查和日志记录,但不能在第二个版本中添加)。您可以通过在容器类中创建索引器来将日志添加到第二个中。@IanNewson-仅删除事件
位会生成类似这样的错误运算符“+”不能与“function(string):void”类型的左侧和“function(string)”类型的右侧一起使用:void.
当您尝试使用c.EventForKey(“a”)+=some_函数时代码>呼叫。