c# - 通过从 C# 中的泛型类派生来创建类型别名
问题描述
我有一个带有一些通用参数的类,在它使用的十几个类中输入这些参数很痛苦。
public abstract class StateBase<StatesList, StateData>
where StatesList : class
where StateData : class
{
public string Name { get; protected set; }
protected StatesList stateList;
protected StateData stateData;
public StateBase(StatesList stateList, StateData stateData)
{
Name = this.GetType().Name;
this.stateList = stateList;
this.stateData = stateData;
}
public abstract bool CanTransitionTo(StateBase<StatesList, StateData> newState);
public abstract void Enter();
public abstract StateBase<StatesList, StateData> Tick();
public abstract void Exit();
}
我熟悉 C/C++ 的 typedef 特性,现在很想念它。我知道 C# 最接近的特性是“使用”指令,它允许您将别名限定为单个文件。我可能会回到那个失败的地方,但是现在,这些课程不断变化,我想要一些更火的东西,然后忘记。
因此,我尝试通过创建一个派生自上述类并填充了所有泛型参数的新类来更优雅地解决别名问题。
public abstract class AIState : StateMachine.StateBase<UnitAIStateList, AIStateData>
{
public abstract override bool CanTransitionTo(AIState newState);
public abstract override void Enter();
public abstract override void Exit();
public abstract override new AIState Tick();
}
你可以猜到,C# 并没有让我那么容易就摆脱它。基类'Tick()
返回通用版本。我的派生类替换为实际类型。看起来它应该可以工作,因为 AIState 是它所要求的一种类型:
'AIState.Tick()': return type must be 'StateBase<UnitAIStateList, AIStateData>' to match overridden member 'StateBase<UnitAIStateList, AIStateData>.Tick()'
我怀疑这个失败的原因是因为 C# 没有实现类型协变,这是我不太熟悉的一个特性。但是,事实上,我对它还不够熟悉,无法真正知道这是否是我的解释。
解决方案
几件事;
1)我会考虑您选择要求您的方法提供StateBase<StatesList, StateData>
类型结果。Tick
您需要使用的绝对最小类型是什么?object
就够了吗?
2)如果您确实需要“与类型相同”的返回值,那么您将不得不以循环方式使用泛型,如下所示:
public abstract class StateBase<StatesList, StateData, TChildType>
where StatesList : class
where StateData : class
where TChildType : StateBase<StatesList, StateData, TChildType> //notice addition of TChildType
{
public string Name { get; protected set; }
protected StatesList stateList;
protected StateData stateData;
public StateBase(StatesList stateList, StateData stateData)
{
Name = this.GetType().Name;
this.stateList = stateList;
this.stateData = stateData;
}
public abstract bool CanTransitionTo(TChildType newState);
public abstract void Enter();
public abstract TChildType Tick();
public abstract void Exit();
}
public class DerivedState : StateBase<string, string, DerivedState>
{
...
}
推荐阅读
- pandas - 将 nunique() 与 groupby 一起使用时出现错误消息
- regex - 用破折号分隔的捕获组
- vue.js - 如何在Vue中将外部html加载为模板或x-template
- z3 - 如何最小化列总和的最大值?
- typescript - typescript tslint react setup中的“'public'只能在.ts文件中使用”?
- reactjs - 将数据从 React Js 发布到 Django Rest
- java - 如果是可选的,我该怎么做
不存在或存在,而是一个空字符串? - php - 如何在应用批量编辑选项(如编辑或移动到垃圾箱)时触发操作?有没有特定的钩子?
- chart.js - 是否可以在 web2py 中使用 Chart.js?
- javascript - 什么是不改变 js 原型的原因?