gpt4 book ai didi

c# - 重载方法..为什么基类优先?

转载 作者:太空狗 更新时间:2023-10-29 22:16:36 25 4
gpt4 key购买 nike

在下面的代码中,我有一个重载方法,一个采用 ClazzA 类型的参数,另一个采用 ClazzB 类型的参数。在显示的代码中,调用了第一个 GetDescription 方法(将 ClazzA 作为参数的方法)。我想我明白为什么了。
我的问题是..如果底层对象的类型是 classB(无需检查每个对象并将其转换为 clazzB),是否有一种优雅的方法可以首先调用采用 clazzB 的方法?

public class ClazzA
{
public virtual string Descr { get { return "A"; } }
}

public class ClazzB : ClazzA
{
public override string Descr { get { return "B"; } }
}

public static class test
{
public static void Main()
{
ClazzA test = new ClazzB();
GetDecription(test);
}

public static void GetDecription(ClazzA someClazz)
{
Debug.WriteLine("I am here");
}

public static void GetDecription(ClazzB someClazz)
{
Debug.WriteLine("I want to be here");
}
}

输出:“我在这里”

我真的很想调用第二种方法,因为“test”是 ClassB 类型。目前我仅有的两个解决方案是:

  1. if(测试是 ClazzB) 返回 GetDescription( (ClazzB) 测试 );

  1. 在 ClassA 中做几乎相同的事情...检查类型并委托(delegate)给第二个方法

这两者都需要检查对象以确定其类型

最佳答案

重载是在编译时确定的。引用的编译时类型是 ClazzA,因此选择了重载。您所要求的与多次 dispatch 有关。 C# 和许多其他语言(如 C++ 和 Java)仅支持单次分派(dispatch)(通过 virtual 方法)。人们想出了很多方法来解决这个问题。最纯粹的 OO 方法是访问者模式。您修改类以包含一个方法 (Accept),然后该方法将 this 引用传递给访问者 (Visit) 上的一个方法。这是可行的,因为您覆盖了每个子类中的 Accept 方法,以便 this 将成为对象的实际类型。所有访问者需要的是您要支持的每个子类的特定方法(有关详细信息,请参阅 wikipedia)。

示例:

public class ClazzA
{
public virtual string Accept(ClassVisitor visitor)
{
return visitor.Visit(this);
}
}

public class ClazzB : ClazzA
{
public override string Accept(ClassVisitor visitor)
{
return visitor.Visit(this);
}
}

public abstract class ClassVisitor
{
public abstract string Visit(ClazzA a);
public abstract string Visit(ClazzB b);
}

public class GetDescriptionVisitor : ClassVisitor
{
public override string Visit(ClazzA a)
{
return "A";
}

public override string Visit(ClazzB b)
{
return "B";
}
}

用法:

ClassVisitor visitor = new GetDescriptionVisitor();
ClazzA b = new ClazzB();
Console.WriteLine(b.Accept(visitor)); // prints "B"

关于c# - 重载方法..为什么基类优先?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13095544/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com