是否可以将泛型参数传递给重载方法?
class Shop
{
void CreateButton<T>(T itemToBuy)
{
var button = CreateButtonImpl();
button.onClick.AddListener(() => Buy(itemToBuy));
}
void Buy(C c) {}
void Buy(D d) {}
}
class C {}
class D {}
在上面的代码中,有一个错误,T无法转换为C.有什么方法可以修复它吗?
答案 0 :(得分:1)
该方法首先不应该是通用的,因为它只能支持两种特定类型,而不是任何类型(在一般意义上它实际上是泛型)
只有Caller
的两个重载,一个接受C
,另一个接受D
。
无法以允许静态类型检查的方式解决此问题。如果您确实必须这样做,那么您可以做的最好的事情是检查参数的类型(即通过is
)并直接调用每个重载。你可以让编译器使用dynamic
为你编写代码,但是你仍然会失去所有的静态类型安全性,并且会受到相当显着的性能影响。
答案 1 :(得分:1)
不,这是不可能的。从调用方那里你可能知道你传入了什么(虽然如果你传递一个基类你也可能不一样),但是从内部你知道的是T
以及你对它的任何限制(没有在这种情况下)。
要执行您想要的操作,您需要获取T
(T.GetType()
)的运行时类型,并将其与其他类的类型进行比较(typeof(C)
和{{分别执行1}},然后执行转换并手动将参数转发到右侧函数。
答案 2 :(得分:0)
我无法在不访问CreateButtonImpl方法的情况下测试代码,但我认为如果将泛型类型声明推送到类级别(远离方法级别),请删除其中一种buy方法,并用接受类型为T的参数替换另一个,您将得到您想要的。这是一个示例:
namespace EmptyConsole
{
class Shop<T>
{
public void CreateButton(T itemToBuy)
{
var button = CreateButtonImpl();
button.onClick.AddListener(() => Buy(itemToBuy));
}
void Buy(T itemToBuy) { }
}
class C { }
class D { }
class Program
{
static void Main(string[] args)
{
var shop = new Shop<C>();
shop.CreateButton(new C());
}
}
}
将C和D类实现相同的接口(创建表示它们可以执行的操作的新接口)并将泛型类型参数T限制为实现该共享接口的东西也是值得的。这是一个修改过的示例,显示了该场景的样子:
namespace EmptyConsole
{
class Shop<T> where T : IPurchaseable
{
public void CreateButton(T itemToBuy)
{
var button = CreateButtonImpl();
button.onClick.AddListener(() => Buy(itemToBuy));
}
void Buy(T itemToBuy) { }
}
interface IPurchaseable { }
class C : IPurchaseable { }
class D : IPurchaseable { }
class Program
{
static void Main(string[] args)
{
var shop = new Shop<C>();
shop.CreateButton(new C());
}
}
}