- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
引用自: http://msdn.microsoft.com/en-us/library/aa645739(VS.71).aspx
“只能从声明事件的类中调用事件。”
我很纳闷为什么会有这样的限制。如果没有这个限制,我将能够编写一个类(一个类),它可以很好地管理发送给定类别的事件——比如 INotifyPropertyChanged。
由于此限制,我必须重新复制并粘贴相同(相同!)的代码。我知道 C# 的设计者不太看重代码重用 (*),但是哎呀……复制和粘贴。这有多高效?
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string name)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(name));
}
}
在每一节课上改变一些东西,直到你生命的尽头。可怕!
所以,当我将我的额外发送类(我太容易上当受骗)恢复为旧的“好”复制和粘贴方式时,你能看到吗
如果您知道如何避免此限制的任何技巧 - 请不要犹豫回答!
(*) 有了多重继承,我可以用更清晰的方式写一次通用发送器,但 C# 没有多重继承
界面介绍
public interface INotifierPropertyChanged : INotifyPropertyChanged
{
void OnPropertyChanged(string property_name);
}
为 PropertyChangedEventHandler 添加新的扩展方法 Raise。然后为这个新接口(interface)添加中介类而不是基本的 INotifyPropertyChanged。
到目前为止,让我们代表其所有者从嵌套对象向您发送消息的代码最少(当所有者需要此类逻辑时)。
感谢大家的帮助和想法。
古法写道:
“您不能通过从外部触发事件来导致某事发生,”
这很有趣,因为...我可以。这正是我要问的原因。看一看。
假设您有类字符串。不有趣,对吧?但是让我们用 Invoker 类打包它,它会在每次更改时发送事件。
现在:
class MyClass : INotifyPropertyChanged
{
public SuperString text { get; set; }
}
现在,当文本更改时,MyClass 也会更改。因此,当我在文本中时,我知道,如果只有我拥有所有者,它也会发生变化。所以我可以代表它发送事件。而且它在语义上是 100% 正确的。
备注:我的类只是更聪明一点——所有者设置它是否想要这样的逻辑。
传递事件处理程序的想法——“2”将不会显示。
public class Mediator
{
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string property_name)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(property_name));
}
public void Link(PropertyChangedEventHandler send_through)
{
PropertyChanged += new PropertyChangedEventHandler((obj, args) => {
if (send_through != null)
send_through(obj, args);
});
}
public void Trigger()
{
OnPropertyChanged("hello world");
}
}
public class Sender
{
public event PropertyChangedEventHandler PropertyChanged;
public Sender(Mediator mediator)
{
PropertyChanged += Listener1;
mediator.Link(PropertyChanged);
PropertyChanged += Listener2;
}
public void Listener1(object obj, PropertyChangedEventArgs args)
{
Console.WriteLine("1");
}
public void Listener2(object obj, PropertyChangedEventArgs args)
{
Console.WriteLine("2");
}
}
static void Main(string[] args)
{
var mediator = new Mediator();
var sender = new Sender(mediator);
mediator.Trigger();
Console.WriteLine("EOT");
Console.ReadLine();
}
作为对所有关于滥用直接事件调用的争论的评论——滥用当然仍然是可能的。只需实现上述解决方法即可。
我的代码的小样本(最终用途),Dan 请看一看:
public class ExperimentManager : INotifierPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string property_name)
{
PropertyChanged.Raise(this, property_name);
}
public enum Properties
{
NetworkFileName,
...
}
public NotifierChangedManager<string> NetworkFileNameNotifier;
...
public string NetworkFileName
{
get { return NetworkFileNameNotifier.Value; }
set { NetworkFileNameNotifier.Value = value; }
}
public ExperimentManager()
{
NetworkFileNameNotifier =
NotifierChangedManager<string>.CreateAs(this, Properties.NetworkFileName.ToString());
...
}
最佳答案
在开始咆哮之前先想一想。如果任何方法都可以调用任何对象上的事件,那会不会破坏封装并且也会造成混淆?事件的意义在于,具有事件的类的实例可以通知其他对象某个事件已经发生。事件必须来自那个类,而不是来自任何其他类。否则,事件变得毫无意义,因为任何人都可以在任何时间触发任何对象上的任何事件,这意味着当事件触发时,您不确定它是否真的是因为它所代表的 Action 发生了,或者仅仅是因为某些第 3 方类决定找点乐子。
就是说,如果您希望能够允许某种中介类为您发送事件,只需打开带有添加和删除处理程序的事件声明即可。然后你可以这样做:
public event PropertyChangedEventHandler PropertyChanged {
add {
propertyChangedHelper.PropertyChanged += value;
}
remove {
propertyChangedHelper.PropertyChanged -= value;
}
}
然后 propertyChangedHelper 变量可以是某种对象,它实际上会触发外部类的事件。是的,您仍然需要编写添加和删除处理程序,但它是相当少的,然后您可以使用任何您想要的复杂性的共享实现。
关于c# - 为什么在 C# 中禁止为发件人发送事件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3642809/
我正在尝试使用 npmpublish 命令发布包。但我每次都会收到此错误。 npm ERR! code E403 npm ERR! 403 Forbidden - PUT https://regist
我在 WAMP 上访问我的本地主机(最后是 phpmyadmin)时遇到问题。 当我输入 localhost或 http://127.0.0.1进入我的浏览器,我收到以下消息: Forbidden Y
我正在尝试发送 $ajax,并且我已经得到了它,但是我必须使用我的表单发送文件,无论是否相同,都没关系。尚未找到 csrf token ,并且出现错误。 我的 JavaScript $(doc
我有一个奇怪的问题,我试图使用请求模块废弃某些页面,但这样做时我收到 403 访问被拒绝。但我完全能够使用 Node 的curl 模块来完成此操作。但互联网上的人们认为,它比请求模块更需要性能,因为我
所以,我正在制作一个公共(public)的不和谐机器人,但我的脚本的一部分有问题。我的 kick/ban 命令是用来完成的 $ban @user 它必须在 ping 中完成。由于这是公开的,我真的很想
我在负载均衡器后面有 2 个服务器。此 LB 上配置了 SSL。将近 50 个不同的客户端能够成功连接到我的网站,除了 1 个客户端从浏览器收到禁止 (403) 消息。 经过一番调查,我发现他在代理服
1、禁止计算局部梯度 torch.autogard.no_grad: 禁用梯度计算的上下文管理器。 当确定不会调用Tensor.backward()计算梯度时,设置禁止计算梯度会减少内存消耗。
如果 Moose 的构造函数调用中有额外的参数不是属性,有没有办法死?例如,这个: package Shoe; use Moose; has 'size' => (is => 'ro', isa =
在服务器上,安装了 Nginx。 Let's Encrypt 在 www.domain.com 上运行良好,但不适用于 static.domain.com 使用 PuTTY,当我输入时:sudo le
我使用 emacs 来编辑所有内容。在我的一些 LateX 文档中,我想在编辑表格和代码时自动禁用自动填充模式。基本上,我想要两个标签,例如: %%% BEGIN NO FILL %%%
通过 Nuget,我将 WindowsAzure.Storage 升级到 8.1.1。 然后,我下载了 AzureStorageEmulator 5.1.0.0 客户端。 我的连接字符串: UseDe
Qt documentation说,信号的返回值是不可能的: Signals are automatically generated by the moc and must not be implem
编辑版本 我有一个关于 GPG 的问题,但我写了所有的过程,也许它会对某人有所帮助。 我想:禁止 GPG 命令中的密码提示。 我不想:使用 -c 选项(--对称)。 我有 2 个系统 Linux 和
现在的想法是这样的:在 Java 中为 octalIntegerLiteral我有一个规则 octalNumeral, (integerTypeSuffix optional) 但我想得到一个数字作为
我在 Python 项目中所有模块的开头使用以下内容: import setup_loggers setup_loggers是一个可以做到这一点的模块。 import语句确保无论首先加载哪个模块,记录
我刚刚下载了最新版本的 XAMPP,PHP 版本为 7.2.4。我为 HTML 表单做了一个非常简单的 PHP 验证,当我按下提交时,它会出现以下内容: Access forbidden!You do
我已经成功运行 Vagrant 大约一个星期了。昨晚我运行了 vagrant reload,现在我无法再访问我的网站。 VirtualBox 版本 4.2.16 Vagrant 版本 1.2.7 我的
我使用以下 JavaScript 代码在完成 ajax 后播放音频: $(document).ready(function () { $.ajaxSetup(
我有一个似乎可以在互联网上运行的应用程序。但我接到了一位最终用户的电话,他在使用website时遇到困难。 我要求她发送控制台错误的屏幕截图并收到以下信息: 从 stackoverflow 搜索来看,
我在尝试提交到 svn 存储库时遇到此错误: svn: MKACTIVITY of '/svn/Demo/!svn/act/e2e65cfa-...4165f': 403 Forbidden (htt
我是一名优秀的程序员,十分优秀!