我希望Foo<T>
要求任何实例化都自己实现T
。 (Foo<>
可以是抽象的,也可以是接口)
或者如果它实际上是MyFoo : IFoo<ConcreteClass>
,那么MyFoo : ConcreteClass
目前我已经通过让Foo<T>
声明类型为T的属性来实现我的基本目标,通常通过返回类本身来满足,但我很好奇我是否可以更直接地执行它。
<小时/> 编辑:我确信自己这是不可能的。 作为参考,有问题的代码如下所示:
public abstract class BotController<TBot> : BotController, IBotController<TBot>
{
protected BotController(TBot wrappedBot, PlayerRecord player, long timeout) : base(player, timeout)
{
WrappedBot = wrappedBot;
}
protected TBot WrappedBot { get; set; }
public abstract TBot ControlledBot { get; }
private string cachedName;
public override string BotName => (cachedName = (cachedName ?? WrappedBot.Name));
protected T SafelyPerformBotActionWithTimer<T>(Func<TBot, T> botAction, string errorDescriptor)
{
return SafelyPerformBotActionWithTimer(() => botAction(WrappedBot), errorDescriptor);
}
protected void SafelyPerformBotActionWithTimer(Action<TBot> botAction, string errorDescriptor)
{
SafelyPerformBotActionWithTimer(() => botAction(WrappedBot), errorDescriptor);
}
}
public class BattleshipsController : BotController<IBattleshipsBot>, IBattleshipsBot
{
public BattleshipsController(IBattleshipsBot battleshipImplementation, PlayerRecord playerRecord, long timeout = 1000)
: base(battleshipImplementation, playerRecord, timeout) {}
public override IBattleshipsBot ControlledBot => this;
public IEnumerable<IShipPosition> GetShipPositions()
{
//qqMDM validate Ship Positions here?
return SafelyPerformBotActionWithTimer(b => b.GetShipPositions(), "specifying ship positions");
}
public IGridSquare SelectTarget()
{
var target = SafelyPerformBotActionWithTimer(b => b.SelectTarget(), "selecting a target");
if (target.IsOutsideGrid())
{
throw new ShotOffBoardException($"{BotName} has tried to shoot off the board, aiming at square {target.Row}{target.Column}", this);
}
return target;
}
public void HandleShotResult(IGridSquare square, bool wasHit)
{
SafelyPerformBotActionWithTimer(b => b.HandleShotResult(square, wasHit), "handling shot result");
}
public void HandleOpponentsShot(IGridSquare square)
{
SafelyPerformBotActionWithTimer(b => b.HandleOpponentsShot(square), "handling opponent's shot");
}
public string Name => BotName;
}
答案 0 :(得分:0)
我想象的具体事情是不可能的。
我想要一些语法:
abstract class Foo<TWrappedType> where Foo : TWrappedType
如果TWrappedType
是一个接口(它将在我的情况下),它在概念上可行,但如果TWrappedType
是一个具体类,则可能永远不会工作,因为C#不进行多重继承。
由于您无法约束Generic Type是接口还是类,因此语法不存在。
当我写这个问题时,我已经走了一半,因此这个问题很混乱,但还不足以证明这是不可能的。
答案 1 :(得分:0)
如果我理解正确,您可以使用中间类/接口执行此操作:
interface IInterface<T>
{ }
class Foo<T> : IInterface<T> where T : IInterface<T>
{
}
但你的问题并不是那么清楚。我不确定这是否与你想要的类似,这种类声明只会让我头疼。
答案 2 :(得分:-1)
为了考虑到这一点的未来人们的利益,最初似乎可以获得一些好处,并在端点处使用相同的语法(Foo<T>
看起来像T
),通过设置显式和隐式转换运算符,只需返回抽象类的property
。
然而,语言中不允许这样做。