在C#中重载抽象泛型方法

时间:2017-12-26 20:41:44

标签: c# generics overloading abstract-methods

我尝试使用类型约束实现通用抽象方法,然后使用不同的指定类型多次实现它。

public abstract class Ability
{
   public abstract void BindToStation<T>(T station) where T : Station;
}

public class DashAbility : Ability
{
    public override void BindToStation<NavStation>(NavStation station){ }
    public override void BindToStation<CannonStation>(CannonStation station){ }
}

但是我得到一个错误,表示该方法已经使用相同的参数类型定义。

我猜测编译器在方法签名方面将任何通用参数视为相同,因此这两种方法看起来相同。

尽管如此,我还是想知道是否可以使用特定类型进行泛型方法重载...?

2 个答案:

答案 0 :(得分:0)

你无法做到你想要的,但你可以尝试这样的方法:

interface IBindableTo<T> where T : Station
{
    void BindToStation(T station);
}

abstract class Ability
{
    public abstract void BindToStation<T>(T station) where T : Station;
}

class DashAbility : Ability, IBindableTo<NavStation>, IBindableTo<CannonStation>
{
    public override void BindToStation<T>(T station)
    {
        if (this is IBindableTo<T> binnder)
        {
            binnder.BindToStation(station);
            return;
        }

        throw new NotSupportedException();
    }

    void IBindableTo<NavStation>.BindToStation(NavStation station)
    {
        ...
    }

    void IBindableTo<CannonStation>.BindToStation(CannonStation station)
    {
        ...
    }
}

希望这有帮助。

答案 1 :(得分:0)

C#不支持这种方式的专业化,当你想专注于运行时类型时,C ++也不容易。

但是你可以使用多态,所以你可以使用double-dispatch:

public abstract class Station {
    internal abstract void DashBindToStation();
}

public class NavStation : Station {
    internal override void DashBindToStation() {
        throw new NotImplementedException();
    }
}

public class CannonStation : Station {
    internal override void DashBindToStation() {
        throw new NotImplementedException();
    }
}

public abstract class Ability {
    public abstract void BindToStation(Station station);
}

public class DashAbility : Ability {
    public override void BindToStation(Station station) {
        station.DashBindToStation();
    }
}

C#的另一种可能性是使用dynamic

来使用运行时调度
public abstract class Station {
}

public class NavStation : Station {
}

public class CannonStation : Station {
}

public abstract class Ability {
    public abstract void BindToStation(Station station);
}

public class DashAbility : Ability {
    public void BindToStation(NavStation station) {
    }
    public void BindToStation(CannonStation station) {
    }

    public override void BindToStation(Station station) {
        BindToStation((dynamic)station);
    }
}