无法确定调用基本构造函数的位置,对事件进行签名

时间:2016-06-20 05:57:12

标签: c# events inheritance constructor delegates

所以,这是我的代码。输出是2255.但我知道为什么A类中的方法将被执行,因为我们还没有在其上签名,因为我们还没有创建A类实例。

using System;
public delegate void EvHappened();
class A{
    protected int a = 0;
    public event EvHappened AEv;
    public A() {
        this.AEv += EvAHappenedHandler;
    }
    public void EvAHappenedHandler(){
        if (a > 3)
            this.a++;
        Console.Write(a);
    }
    public void methodA() {
        this.AEv();
    }
}

class B : A{
    public event EvHappened BEv;
    public void EvBHappenedHandler() {
        this.a += 2; methodA(); Console.Write(a);
    }
    public void method(){
        this.BEv();
    }
}
class Program{
    static void Main(string[] args){
        B b = new B();
        b.BEv += b.EvBHappenedHandler;
        for (int i = 0; i < 2; i++){
            b.method();
        }
    }
}

3 个答案:

答案 0 :(得分:1)

由于你还没有在B中声明任何构造函数,编译器提供了一个默认的构造函数 - 就像你写的那样:

public class B {
    public B() : base() {
    }

    // Rest of class here
}

因此,当您致电new B()时,A构造函数将被执行。该构造函数订阅AEv事件。

如果 自己声明了构造函数,则行为将取决于构造函数初始化程序

  • 使用this(...)形式的构造函数初始值设定项,构造函数将链接到同一个类中的另一个构造函数。最终这个&#34;链&#34;最终会调用基类中的构造函数。
  • 使用base(...)形式的构造函数初始值设定项,构造函数将链接到基类中的指定构造函数。
  • 如果您根本没有指定构造函数初始值设定项,则它等同于base()形式之一。

所以无论你在派生类中做什么,任何构造函数总是最终通过基类中的构造函数。

答案 1 :(得分:0)

是。实例化B类时调用A类的构造函数

EvAHappenedHandler

反过来,注册处理程序。 A类的设计基本上是说派生类无权改变继承的行为。如果你想要相反至少使{{1}}虚拟。

答案 2 :(得分:0)

这是纯粹的 OOP

当您创建继承A类的对象B时,将调用A的构造函数。

示例:

class A
{
    public A()
    {
        Console.WriteLine("Constructor Of A");
    }
}

class B : A
{
    public B()
    {
        Console.WriteLine("Constructor Of B");
    }

    public void method()
    {

    }
}

<强>用法:

B b = new B();

<强>输出:

Constructor Of A
Constructor Of B

如果您真的需要在不运行构造函数的情况下创建类B

B b = (B)FormatterServices.GetUninitializedObject(typeof(B));

注意:根据MSDN,除非你知道自己在做什么,否则不应该使用它。

  

因为对象的新实例初始化为零而没有   运行构造函数,对象可能不代表状态   被该物体视为有效。目前的方法应该只是   用户打算立即填充时用于反序列化   所有领域。自创建以来,它不会创建未初始化的字符串   不可变类型的空实例没有用处。