Перегрузка абстрактных обобщенных методов в C#
Я пытаюсь реализовать общий абстрактный метод с ограничением типов, а затем реализовать его несколько раз, используя различные указанные типы.
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 ответа
Вы не можете делать именно то, что вы хотите, но вы можете попробовать такой подход:
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)
{
...
}
}
Надеюсь это поможет.
C# не поддерживает специализацию таким образом, как и C++, когда вы хотите специализироваться на типе времени выполнения.
Но вы можете использовать полиморфизм, поэтому вы можете использовать двойную диспетчеризацию:
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);
}
}