相关疑难解决方法(0)

let_ property方法的好奇心

每个.net开发人员都知道属性的概念.粗略的99.99%,它只是一个元数据粘合在一起的两个方法,一个吸气剂和一个设定器.

通常使用add,remove和invoke方法对事件也是如此.

ECMA-335描述了一种"其他"方法语义,适用于属性或事件.从概念上讲,财产或事件可能有多种"其他"方法.

今天是我用"其他"方法偶然发现房产的第一天.当然,它必须与COM有关.EnvDTE程序集中的EnvDTE.Property接口(用于向Visual Studio编写插件)包含一个定义如下的属性:

.property object Value()
{
  .custom instance void [mscorlib]System.Runtime.InteropServices.DispIdAttribute::.ctor(int32) = ( 01 00 00 00 00 00 00 00 ) 
  .get instance object EnvDTE.Property::get_Value()
  .other instance void EnvDTE.Property::let_Value(object)
  .set instance void EnvDTE.Property::set_Value(object)
}
Run Code Online (Sandbox Code Playgroud)

将let_Value定义为:

.method public hidebysig newslot specialname abstract virtual 
        instance void  let_Value([in] object  marshal( struct) lppvReturn) runtime managed internalcall
{
  .custom instance void [mscorlib]System.Runtime.InteropServices.DispIdAttribute::.ctor(int32) = ( 01 00 00 00 00 00 00 00 ) 
}
Run Code Online (Sandbox Code Playgroud)

显然,VB.NET之前的VBScript和VB版本可以使用Let关键字定义属性.并且Let与Set具有相同的签名.我觉得这里有关系.

但有没有人知道这个属性是如何用EnvDTE编写的语言声明的?我怎么能用相同的模式创建一个程序集(不使用ilasm,这太容易了)?还有人遇到类似的财产吗?

有没有人见过其他"其他"属性,可能与这个属性有不同的语义?如果是的话,他们习惯了什么?

.net cil

16
推荐指数
1
解决办法
695
查看次数

相当于VB在C#中的自定义RaiseEvent块?

(我知道标题听起来很容易,但坚持 - 这可能不是你认为的问题.)

在VB.NET中,我能够编写自定义事件.举个例子,我有一个单独的线程会定期引发事件,在那个事件上需要更新GUI.我不希望繁忙的线程打扰UI计算,我不想把Me.Invoke(Sub()...)放在事件处理程序中,因为它也是从GUI线程调用的.

我想出了这个非常有用的代码.GUI线程将设置EventSyncInvoke = Me(主窗体).然后线程可以像往常一样简单地引发事件TestEvent,没有特殊代码,它将在GUI线程上无缝执行:

Private TestEventDelegate As EventHandler
Public EventSyncInvoke As System.ComponentModel.ISynchronizeInvoke

Public Custom Event TestEvent As EventHandler
    AddHandler(value As EventHandler)
        TestEventDelegate = [Delegate].Combine(TestEventDelegate, value)
    End AddHandler

    RemoveHandler(value As EventHandler)
        TestEventDelegate = [Delegate].Remove(TestEventDelegate, value)
    End RemoveHandler

    RaiseEvent(sender As Object, e As System.EventArgs)
        If EventSyncInvoke IsNot Nothing Then
            EventSyncInvoke.Invoke(TestEventDelegate, {sender, e})
        Else
            TestEventDelegate.Invoke({sender, e})
        End If
    End RaiseEvent
End Event
Run Code Online (Sandbox Code Playgroud)

现在在C#中,我可以做到这一点:

public event EventHandler TestEvent
    add
    {
        testEventDelegate = (EventHandler)Delegate.Combine(testEventDelegate, value);
    }
    remove
    {
        testEventDelegate = (EventHandler)Delegate.Remove(testEventDelegate, value); …
Run Code Online (Sandbox Code Playgroud)

c# events

12
推荐指数
2
解决办法
3万
查看次数

为什么事件不提供3种访问方法?

当执行事件,一个可以提供代码addremove事件处理程序.但是,可以通过三种方式访问​​事件:

MyEvent += Handler;                // add accessor
MyEvent -= Handler;                // remove accessor
MyEvent(this, EventArgs.Empty);    // not supported by an accessor
Run Code Online (Sandbox Code Playgroud)

是否有另一个称为invoke负责的访问者是不是很明显?我的想法是:

class BaseClass
{
  public virtual event EventHandler MyEvent { add; remove; protected invoke; }
}

class DerivedClass : BaseClass
{
  public override event EventHandler MyEvent
  {
    invoke
    {
      // new code before event
      base.MyEvent(this, ...);
      // new code after event
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

我知道旧式模式,即实现OnMyEvent(...)方法.但这种方法存在两个重要缺点:

  1. 事件代码分散 - >组织代码基础较少
  2. 你不能轻易地重构事件(例如,重命名) …

c#

4
推荐指数
1
解决办法
131
查看次数

标签 统计

c# ×2

.net ×1

cil ×1

events ×1