以下是我用于测试的程序.它打印(如预期):
Raise A
Event from A
Raise B
Event from B
Run Code Online (Sandbox Code Playgroud)
现在,如果我们改变Main的前两行是:
A a = new B();
B b = new B();
Run Code Online (Sandbox Code Playgroud)
该计划将打印:
Raise A
Raise B
Event from B
Run Code Online (Sandbox Code Playgroud)
这也是预期的,因为重写事件会隐藏基类中的私有支持字段,因此基类触发的事件对派生类的客户端不可见.
现在我将相同的行改为:
B b = new B();
A a = b;
Run Code Online (Sandbox Code Playgroud)
程序开始打印:
Raise A
Raise B
Event from A
Event from B
Run Code Online (Sandbox Code Playgroud)
这是怎么回事?
class A
{
public virtual event EventHandler VirtualEvent;
public void RaiseA()
{
Console.WriteLine("Raise A");
if (VirtualEvent != null)
{
VirtualEvent(this, EventArgs.Empty);
}
}
}
class B : …Run Code Online (Sandbox Code Playgroud) 我正在编写单元测试并在尝试从抽象类mock中引发事件时收到异常.以下是示例代码:
public abstract class AbstractBase : EntityObject
{}
[TestMethod]
public void MyTest()
{
var mock = new Mock<AbstractBase>();
var notificationMock = entityMock.As<INotifyPropertyChanged>();
var propertyChangedMapper = new PropertyChangedMapper();
bool eventReceived = false;
propertyChangedMapper.MyPropertyChanged +=
(sender, eventArgs) =>
{
eventReceived = true;
};
propertyChangedMapper.Subscribe((AbstractBase)notificationMock.Object);
Assert.IsFalse(eventReceived);
notificationMock.Raise(e=>e.PropertyChanged += null,
new PropertyChangedEventArgs("Property1"));
Assert.IsTrue(eventReceived);
}
Run Code Online (Sandbox Code Playgroud)
显然我可以使用mock on INotifyPropertyChanged并且事件上升得很好,但是PropertyChangedMapper我需要将发送者强制转换AbstractBase为失败的Mock<INotifyPropertyChanged>
编辑:根据建议使用Mock.As<>()似乎是正确的方法,上面唯一的问题是,事件的上升notificationMock与对象的原始模拟无关.码:
notificationMock.Object.PropertyChanged += (s, e) =>
{
var result = "this one is fired as it …Run Code Online (Sandbox Code Playgroud) 最近我发现虚拟事件不像C#中所期望的那样工作.考虑以下代码:
public abstract class MyClassBase
{
public virtual event EventHandler<EventArgs> MyEvent;
public void DoStuff()
{
if (MyEvent != null)
{
MyEvent(this, EventArgs.Empty);
}
}
}
public class MyClassDerived : MyClassBase
{
public override event EventHandler<EventArgs> MyEvent;
}
Run Code Online (Sandbox Code Playgroud)
鉴于此定义,以下代码的行为与我的预期不符:
MyClassBase obj = new MyClassDerived();
obj.MyEvent += (s, e) => { /* Never gets called */ };
// Call method on base class that raises MyEvent
obj.DoStuff();
Run Code Online (Sandbox Code Playgroud)
我在我的博客上做了一些更广泛的写作,但足以说我在MSDN上发现了一个警告,确认行为是意外的,但它没有说明原因.任何人都可以想到它以这种方式实施的原因吗?它原本是一个为了向后兼容而留下的错误吗?我认为至少可以添加某种编译器警告.
我意识到这很可能是猜测,但我试图为这种奇怪的行为找到合理的解释.