Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/292.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将泛型参数传递给重载方法_C# - Fatal编程技术网

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。关键字的明确用途是删除所有涉及任何<代码>动态类型的表达式的所有静态类型检查。