C# 将泛型参数传递给重载方法
是否可以将泛型参数传递到重载方法中C# 将泛型参数传递给重载方法,c#,C#,是否可以将泛型参数传递到重载方法中 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 {} class商店 {
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 {}
class商店
{
void CreateButton(T itemToBuy)
{
var button=CreateButtonImpl();
button.onClick.AddListener(()=>Buy(itemToBuy));
}
无效购买(C){}
无效购买(D){}
}
类C{}
类D{}
在上面的代码中,有一个错误T不能转换为C。有什么方法可以修复它吗?该方法首先不应该是泛型的,因为它只能支持两种特定类型,而不能支持任何类型(使它实际上是一般意义上的泛型) 只需对
调用者执行两个重载,一个接受C
,另一个接受D
没有办法以允许静态类型检查的方式解决此问题。如果确实必须这样做,那么最好检查参数的类型(即通过is
)并直接调用每个重载。您可以让编译器使用dynamic
为您编写代码,但这样您仍然会失去所有静态类型安全性,并且会受到相当显著的性能影响。不,这是不可能的。从调用方的角度,您可能知道要传递什么(虽然传递基类时可能不太好),但从内部,您所知道的只是T
以及您对它施加的任何限制(在本例中没有)
要执行所需操作,您需要获取该T
(T.GetType()
)的运行时类型,并将其与那些其他类的类型进行比较(typeof(C)
和typeof(D)
),然后执行强制转换并手动将参数转发到正确的函数。如果不访问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());
}
}
}
namespace-EmptyConsole
{
班级商店
{
公共无效创建按钮(T itemToBuy)
{
var button=CreateButtonImpl();
button.onClick.AddListener(()=>Buy(itemToBuy));
}
无效购买(T itemToBuy){}
}
类C{}
类D{}
班级计划
{
静态void Main(字符串[]参数)
{
var shop=新店铺();
CreateButton(新的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());
}
}
}
namespace-EmptyConsole
{
可购买T:I的班级商店
{
公共无效创建按钮(T itemToBuy)
{
var button=CreateButtonImpl();
button.onClick.AddListener(()=>Buy(itemToBuy));
}
无效购买(T itemToBuy){}
}
接口可购买{}
C类:可购买的{}
D类:可购买的{}
班级计划
{
静态void Main(字符串[]参数)
{
var shop=新店铺();
CreateButton(新的C());
}
}
}
C
和D
有什么共同点吗?@YuvalItzchakov:没有,它们大部分是不相关的。@Grantwiney:目前没有,但noop就足够了。使用动态
会失去什么类型的安全性?@JurajBlaho。关键字的明确用途是删除所有涉及任何<代码>动态代码>类型的表达式的所有静态类型检查。