处理通用参数的最佳方法是什么?

时间:2020-03-25 16:39:30

标签: c# generics

如果我想创建一个使用泛型将任何类型的类型接受为参数的Init()方法,我是否需要针对要在该方法主体内部处理的每种不同类型进行显式转换...

这是正确的吗?如果是的话,它有什么含义吗?

void Init<T>(T initParam)
{
   var enemy = initParam as Enemy;
   Console.WriteLine(enemy.ToString());
}

我想做的是有几种类型的敌人实现一个接口IEnemy,我当时在想接口可以只有一个Init()方法,这样我就可以在每个IEnemy上实现Init()逻辑。实施方式和参数类型不同:

class SuperEnemy: IEnemy
{
   public void Init<T>(T enemyParams)
   {
       // In this case I need EnemySuperPowers 
       var superPowers = enemyParams as EnemySuperPowers;
   }
}

3 个答案:

答案 0 :(得分:6)

不,泛型被称为泛型,因为这意味着强制实施是泛型。这意味着当您看到一种方法时:

void Foo<T>(T t) { ... }

如果Foo的实现根本不关心T的真正含义,则可以正确使用泛型(有例外,但一般规则几乎总是适用)。

另一方面,如果在Foo内部需要根据T的实际情况采取不同的操作,那么泛型就不是可行的方法,最好不要重载:

void Foo(Enemy enemy) { ... }
void Foo(Neutral neutral) { ... }
//etc.

答案 1 :(得分:1)

您的更新清楚地说明了为什么您认为需要泛型,而且的确步入正轨。

但是,除了使方法通用,您还可以使界面通用以指示不同类型的Power

interface IEnemy<TPower> where TPower : Power
{
    void Init(TPower param);
}

您的类SuperEnemy使用通用参数EnemySuperPower实现该接口:

class SuperEnemy : IEnemy<EnemySuperPowers>
{
    public void Init(EnemySuperPowers enemyParams)
    {
        // now you don´t need to cast anymore, because param already is of the type
        EnemySuperPowers superPowers = enemyParams;
    }
}

而另一个敌人可以拥有这个:

class ApocalypticEnemy : IEnemy<DestroyWorldPower>
{
    public void Init(DestroyWorldPower param) { ... }
}

答案 2 :(得分:-3)

我是否需要对要在体内处理的每种不同类型进行显式转换

是的

C#中的惯用法是Type Pattern

void Init<T>(T initParam)
{
   if (initParam is Enemy enemy)
   {
       Console.WriteLine(enemy.ToString());
   }
   //. . .
}