在.NET中,如果我正在实现一个包含事件的接口,但该事件对我的对象毫无意义(说它是一个更改事件而我正在编写一个不可变对象),那么我只能提供空add
和remove
的实体 - 空实现。这样可以避免为我永远不会使用的委托字段分配存储空间,并且还避免了“事件永远不会被使用”编译器警告,因此这是一个全面的胜利。
public event EventHandler Changed {
add {}
remove {}
}
当我在WinRT类中尝试相同的事情(从FrameworkElement继承)时,我在add
访问器上遇到编译器错误:“并非所有代码路径都返回值”。
如何从add
访问者返回值?应该归还什么?
更新:显然此问题仅适用于WinRT事件(例如,如果您正在实现包含事件的WinRT接口)。如果您正在编写一个普通的旧CLR事件,则上述语法有效。
答案 0 :(得分:6)
我在Windows开发人员中心找到了this文章。似乎add
和remove
访问者功能确实已经改变了Metro:
.NET Runtime的.NET Framework支持通过隐藏Windows运行时事件模式和.NET Framework事件模式之间的差异,可以轻松地在Windows运行时组件中声明事件。但是,在Windows运行时组件中声明自定义事件访问器时,必须遵循Windows运行时模式。
当您注册在Windows运行时中处理事件时,添加访问器会返回一个令牌。要取消注册,请将此令牌传递给删除访问者。这意味着Windows运行时事件的添加和删除访问器与您习惯使用的访问器具有不同的签名。
幸运的是,Visual Basic和C#编译器简化了这个过程:当您在Windows运行时组件中使用自定义访问器声明事件时,编译器会自动使用Windows运行时模式。例如,如果添加访问者未返回令牌,则会出现编译器错误。
.NET Framework提供了两种类型来支持实现:
- EventRegistrationToken结构代表令牌。
- EventRegistrationTokenTable< T> class创建标记并维护标记和事件处理程序之间的映射。泛型类型参数是事件参数类型。您可以为每个事件创建此类的实例,这是第一次为该事件注册事件处理程序。
答案 1 :(得分:4)
因此,根据Anders posted链接,add
访问者看起来需要返回EventRegistrationToken
。 EventRegistrationToken
只是一个结构,显然没有字段,也没有超出默认值的构造函数,因此看起来我可以无害new
一个 - 特别是因为唯一会消耗它的代码是我的{ {1}},无关紧要。
因此,null事件的WinRT等价物似乎是:
remove