Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/279.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# `as`会启用多态性吗?是否将继承的类传递给采用基类启用多态性的方法?_C#_.net_Polymorphism_As Operator - Fatal编程技术网

C# `as`会启用多态性吗?是否将继承的类传递给采用基类启用多态性的方法?

C# `as`会启用多态性吗?是否将继承的类传递给采用基类启用多态性的方法?,c#,.net,polymorphism,as-operator,C#,.net,Polymorphism,As Operator,首先,我将使用virtual和override 例如,基类A有方法A.do(),继承的类B有覆盖A的方法B.do() 如果我调用(B作为A).do(),它将执行哪个do() 或者,如果有一个方法voidmymethod(aa){a.do()},现在我通过bb调用它;mymethod(b),它会执行b.do() 始终会调用最顶层的重写方法,即b.Do()或(b作为A.Do()或((A)b)。Do()将调用b.Do() 如果子类重写基类方法,我不知道如何从子类调用它。总是调用最顶层的重写方法,即b.

首先,我将使用
virtual
override

例如,基类A有方法
A.do()
,继承的类B有覆盖A的方法
B.do()

如果我调用
(B作为A).do()
,它将执行哪个
do()


或者,如果有一个方法
voidmymethod(aa){a.do()}
,现在我通过
bb调用它;mymethod(b)
,它会执行
b.do()

始终会调用最顶层的重写方法,即
b.Do()
(b作为A.Do()
((A)b)。Do()
将调用
b.Do()


如果子类重写基类方法,我不知道如何从子类调用它。

总是调用最顶层的重写方法,即
b.Do()
(b作为a.Do()
((a)b)。Do()
将调用
b.Do()

public class A
{
    public virtual void Do() { Console.Write("a"); }
    public void Do2() { Console.Write("a2"); }
}

public class B : A
{
    public override void Do() { Console.Write("b"); }
    public new void Do2() { Console.Write("b2"); }
}

class Program
{
    static void Main(string[] args)
    {
        B b = new B();
        A a = b;
        b.Do();               //b
        ( b as A ).Do();      //b
        a.Do();               //b
        ( (A)b ).Do();        //b

        ( b as A ).Do2();     //a2
        ( (A)b ).Do2();       //a2
        ( b ).Do2();          //b2
    }
}  
我不知道如果子类重写基类方法,如何从子类调用它

public class A
{
    public virtual void Do() { Console.Write("a"); }
    public void Do2() { Console.Write("a2"); }
}

public class B : A
{
    public override void Do() { Console.Write("b"); }
    public new void Do2() { Console.Write("b2"); }
}

class Program
{
    static void Main(string[] args)
    {
        B b = new B();
        A a = b;
        b.Do();               //b
        ( b as A ).Do();      //b
        a.Do();               //b
        ( (A)b ).Do();        //b

        ( b as A ).Do2();     //a2
        ( (A)b ).Do2();       //a2
        ( b ).Do2();          //b2
    }
}  
输出:

b b b b
a2 a2 b2
输出:

b b b b
a2 a2 b2

这完全取决于do()方法是否声明为虚拟。如果它不是虚拟的,则调用A.do()。如果它是虚拟的,则调用B.do()。它是启用多态性并允许调用独立于引用类型的方法的虚拟关键字


C#中没有允许从B对象引用直接调用虚拟a.do()方法的机制。唯一的例外是在类B的实例方法中使用base.do()。

这完全取决于do()方法是否声明为虚拟。如果它不是虚拟的,则调用A.do()。如果它是虚拟的,则调用B.do()。它是启用多态性并允许调用独立于引用类型的方法的虚拟关键字

public class A
{
    public A() { }
    public void Do() { Console.Write("A"); }

}

public class B : A
{
    public B() { }
    public void Do() { Console.Write("B");  }
}

class Program
{
    static void Main(string[] args)
    {
        B b = new B();
        b.Do(); //<-- outputs B
        (b as A).Do(); //<-- outputs A
      }
}
C#中没有允许从B对象引用直接调用虚拟a.do()方法的机制。唯一的例外是在类B的实例方法中使用base.do()

public class A
{
    public A() { }
    public void Do() { Console.Write("A"); }

}

public class B : A
{
    public B() { }
    public void Do() { Console.Write("B");  }
}

class Program
{
    static void Main(string[] args)
    {
        B b = new B();
        b.Do(); //<-- outputs B
        (b as A).Do(); //<-- outputs A
      }
}
重写方法时,调用B两次


当方法被重写时,调用B两次。

让我用另一个问题回答您的问题:在测试此代码时调用了哪一个?顺便说一句,
as
操作符作用于对象实例,而不是像您的示例中那样作用于类型。似乎您希望显示多态性这不是覆盖而是隐藏。正是由于这个原因,您从编译器那里得到了一个警告。让我用另一个问题来回答您的问题:您测试此代码时调用了哪一个?顺便说一句,
as
操作符作用于对象实例,而不是像您的示例中那样作用于类型。似乎您希望显示多态性这不是覆盖而是隐藏。正是由于这个原因,您从编译器那里得到了警告。实际上,它将调用
B.Do()
,直到
B:a
为止。您确定吗?当你建议某人运行代码时,也许你应该先运行它。@Nahum,abatishchev是正确的。无论您通过(-1)到达它的引用是如何声明的,动态分派都是有效的。没有什么好尴尬的。重要的是,您现在实际测试了代码并发布了正确的答案。这就是为社区带来价值的原因。我已经用赞成票代替了我的反对票,希望其他人也这样做。实际上它会调用
B.do()
,直到
B:A
你确定吗?当你建议某人运行代码时,也许你应该先运行它。@Nahum,abatishchev是正确的。无论您通过(-1)到达它的引用是如何声明的,动态分派都是有效的。没有什么好尴尬的。重要的是,您现在实际测试了代码并发布了正确的答案。这就是为社区带来价值的原因。我已经用赞成票代替了我的反对票,希望其他人也这样做。是的,我会重新编辑,所以要明确我走的是正确的多元主义道路。。虚拟+重写如果
A.Do()
不是虚拟的,因此
B.Do()
不会重写它,而是隐藏(带有适当的编译器警告)-那么
B.Do()
无论如何都会被调用,不是吗?@abat-否,当对象引用是类型A时,会显式调用或通过强制转换调用.Do()。试试看:)是的,我会重新编辑,所以要明确我是用正确的方式进行多元文化。。虚拟+重写如果
A.Do()
不是虚拟的,因此
B.Do()
不会重写它,而是隐藏(带有适当的编译器警告)-那么
B.Do()
无论如何都会被调用,不是吗?@abat-否,当对象引用是类型A时,会显式调用或通过强制转换调用.Do()。试试看:)sry,我想用
virtual
override
sry,我想用
virtual
override