【问题标题】:overloading with runtime type in c#在 C# 中使用运行时类型重载
【发布时间】:2021-06-19 13:04:30
【问题描述】:

考虑以下代码:

public class A
{
    public A(){}
}

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

public class C
{
    public C(){}
    
    public void fun(A a)
    {
        Console.WriteLine("that was A");
    }
    
    public void fun(B b)
    {
        Console.WriteLine("that was B");
    }
}

public class Program
{
    public static void Main()
    {
        A a = new A(), b = new B();
        C c = new C();
        c.fun(a);
        c.fun(b);
    }
}

在当前形式中,它说"that was A" 两次。如何修复类C,使得b的运行时类型为B,但编译类型为A时调用fun(B b)?目前它只有在我在编译期间将b 声明为B 时才能正常工作。

@Edit:不使用ifs 等检查类型。

【问题讨论】:

  • 您将b 声明为A 类型,因此可用的静态类型信息导致它调用fun(A)。避免像这样在同一个语句中声明两个变量。
  • 所以我想你可能想看看后期绑定(编辑:动态调度感谢其他评论者)。本质上,在 C#(和其他语言)中,重载解析是在编译时完成的。 OOP 语言中称为访问者模式或双重调度的模式通常用于处理此问题
  • 正确的解决方案是在 A 上使用虚方法让两种类型提供相同方法的不同实现,而不是为不同类型提供多个重载。
  • c.fun((dynamic)b); 是您要编写的内容...确实,正如@madreflection 暗示的那样,这是在进行疯狂的反射...但在某种程度上C#确实支持它...有时可能是对访问者模式有用(您不能将代码推送为元素上的虚拟方法)...

标签: c# inheritance types runtime overloading


【解决方案1】:

通过虚拟方法调用fun

public class A
{
    public virtual void fun(C c) 
    {
        c.fun(this);
    }
}

public class B:A
{
    public override void fun(C c) 
    {
        c.fun(this);
    }
}

public class C
{
    public void fun(A a)
    {
        Console.WriteLine("that was A");
    }

    public void fun(B b)
    {
        Console.WriteLine("that was B");
    }
}

public class Program
{
    public static void Main()
    {
        A a = new A(), b = new B();
        C c = new C();
        a.fun(c);
        b.fun(c);
    }
}

输出:

that was A
that was B

See example on Fiddle

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-07
    • 2015-11-23
    • 1970-01-01
    • 2013-12-04
    • 2011-05-01
    • 1970-01-01
    相关资源
    最近更新 更多