gpt4 book ai didi

c# - 关于方法参数类型的多态性

转载 作者:行者123 更新时间:2023-11-30 15:30:00 25 4
gpt4 key购买 nike

我想我有一个很常见的问题,但我真的可以想出一个解决方案..

想象一下这个类:

public class ListHandlerBase
{
public virtual void Add(object item)
{
// XXX
}
}


public class ListHandler : ListHandlerBase
{
List<object> ObjectList = new List<object>();
List<string> StringList = new List<string>();
List<int> IntList = new List<int>();

public override void Add(object item)
{
HandleAdd(item);
}

private void HandleAdd(object item)
{
ObjectList.Add(item);
}

private void HandleAdd(string item)
{
StringList.Add(item);
}

private void HandleAdd(int item)
{
IntList.Add(item);
}
}

它有一个 Add 方法接受非常通用的类型对象。然而,有几种方法可以处理对象,但只有“HandleAdd(object item)”会被调用,因为 item 是对象类型(即使它实际上是一个字符串)。为此,我想要某种虚拟/覆盖。

有一个丑陋的解决方案可能看起来像这样:

    public void Add(object item)
{
if(item is string) HandleAdd((string)item);
else if (item is int) HandleAdd((int)item);
else HandleAdd(item);
}

我必须列出所有类型的完整列表,这听起来不是解决问题的好办法。

无论如何我都可以按照我想要的方式调用“正确”的方法吗?

更新:为了使问题更加复杂,我添加了一个基类。这就是为什么我不能有多个添加方法,因为基类不知道 ListHandler 可以接受哪些对象类型。调用 ListHandler 类的类不知道它的细节。我也认为我可以自己回答我的问题。这是一个多重调度问题,我认为如果没有访问者模式,它就无法在 C# 中解决。

最佳答案

首先,我认为这是一种代码味道。我会尝试找到一些不需要这个的替代设计。但是,如果不了解您要解决的实际问题,就很难为您提供帮助。

现在,针对您的实际问题:

It's a multiple dispatch problem and I don't think it can not be solved in C# without the visitor pattern.

这不是多重分派(dispatch)问题的常见版本:你分派(dispatch)的类型不在你的控制之下(所以你不能向它们添加 AcceptVisitor())并且类型列表也不同每个派生类型(因此您不能创建固定的 IVisitor )。

但您实际上可以在 C# 中使用 dynamic 解决此问题.确切的解决方案取决于您是否愿意制作 HandleAdd()重载 public 与否。如果你能做到,那就调用HandleAdd()来自你的 Add() , 使用 dynamic对于 thisitem :

public abstract class ListHandlerBase
{
public void Add(object item)
{
((dynamic)this).HandleAdd((dynamic)item);
}
}

public class ListHandler : ListHandlerBase
{
List<object> ObjectList = new List<object>();
List<string> StringList = new List<string>();
List<int> IntList = new List<int>();

public void HandleAdd(object item)
{
ObjectList.Add(item);
}

public void HandleAdd(string item)
{
StringList.Add(item);
}

public void HandleAdd(int item)
{
IntList.Add(item);
}
}

如果你想保留HandleAdd()私有(private)的,那么你将不得不从派生类本身调用它。这意味着制作 Add()在基类中抽象并使用 dynamic 实现它在每个派生类中(这一次,您不需要 dynamic 上的 this ):

public abstract class ListHandlerBase
{
public abstract void Add(object item);
}

public class ListHandler : ListHandlerBase
{


public override void Add(object item)
{
HandleAdd((dynamic)item);
}


}

关于c# - 关于方法参数类型的多态性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22805826/

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