c# - 可以表示多个不同类的数据类型,这些类具有一些共同的属性,无需继承
问题描述
我正在统一使用 c#。我有一个名为 CarPart 的类,它派生自 MonoBehaviour(MB 是每个统一脚本的基类)。在这个类中,我声明了不能从任何基类派生的特定汽车零件类,因为统一检查器不会显示它们的属性,但它们需要单声道行为,所以我在从 MonoBehaviour 派生的类 (CarPart) 中声明了它们。
public class CarPart : MonoBehaviour {
[System.Serializable] //required to show full objects in inspector
public class Chassis {
//common properties for all car parts
public GameObject prefab;
public int price;
//specific properties for every car part
public bool AWD;
public int suspensionDepth;
//specific implementation of equip for chassis
public void equip() {
//instantiate chassis as root object
}
}
[System.Serializable] //required to show full objects in inspector
public class Engine {
//common properties for all car parts
public GameObject prefab;
public int price;
//specific properties for every car part
public bool supportsAddOnExhaust;
public int power;
//specific implementation of Equip for engine
public void Equip() {
//instantiate engine as child object of chassis in hierarchy
}
}
//this code is heavily simplified
}
然后我有类 VehicleConfig,它是经理游戏对象的组件(这个 GO 在整个游戏中都处于活动状态)。VehicleConfig 与 GUI 通信并基于 GUI 输入配置车辆。它还声明了所有汽车组件,这些组件稍后将分配有来自检查器(功率、悬架深度)和 3D 模型(预制件)的特定值。
public class VehicleConfig : CarPart{
public Chassis[] chassis; //assigned from inspector
public Engine[] engines; //assigned from inspector
//and more car components like these two...
//arrays because there will be multiple to chose from each type
public void Setup (unknownDataType component) {
component.Equip;
DoSomethingWithCommonVariables(component.price, component.prefab);
}
//method called from GUI example:
public void MountFirstEngine() {
Setup(engines[0]);
}
}
我的问题是,我有更多特定的汽车组件,而不仅仅是引擎和底盘,而且它们都有更多的通用方法和特定的实现,然后只是 Equip()。Setup() 也比上面的例子复杂一点。所以我希望 Setup() 用一些数据类型重载,这些数据类型可以表示所有汽车部件(引擎、底盘......)的所有常用方法和属性,所以我可以重载 Setup(),例如将 Engines[0] 转换为那个特殊的数据类型。我知道有不同的方法可以用抽象类来实现这个功能,所有常见的抽象方法都是从中派生的引擎或机箱等类,并且会为这些方法提供某些实现,但正如我之前提到的,统一检查器无法显示派生类的成员变量。如果有人有建议、想法或完全不同的方法。我真的很感激提前提到它:) thx。
解决方案
我不太确定抽象类有什么问题,但是您可以使用抽象类来实现您想要的并在检查器中提供可用的属性:
public abstract class CarElement
{
//common properties for all car parts
public GameObject prefab;
public int price;
public abstract void Equip();
}
[System.Serializable] //required to show full objects in inspector
public class Chassis : CarElement
{
//specific properties for every car part
public bool AWD;
public int suspensionDepth;
public override void Equip() { }
}
[System.Serializable] //required to show full objects in inspector
public class Engine : CarElement
{
//specific properties for every car part
public bool supportsAddOnExhaust;
public int power;
public override void Equip(){ }
}
public class VehicleConfig : CarPart
{
public Chassis[] chassis; //assigned from inspector
public Engine[] engines; //assigned from inspector
//and more car components like these two...
//arrays because there will be multiple to chose from each type
public void Setup(CarElement component)
{
component.Equip();
DoSomethingWithCommonVariables(component.price, component.prefab);
}
//method called from GUI example:
public void MountFirstEngine()
{
Setup(engines[0]);
}
}
推荐阅读
- vue.js - 包括在 Vue.js 中与 Tabulator 一起使用的 Moment.js 库的问题
- r - 如何动态更改数据框中列的数据类型
- typescript - 有没有办法在 Typescript 中使用泛型强制类型动态相同?
- java - 等待一个锁解锁,解锁后不加锁
- ios - 当我使用 Swift 4.2 和 iOS12 向左滑动时,如何将第二个数组加载到 UITableView 中?
- spring-boot - Java 11 + QueryDSL 4 + Gradle 5 + SpringBoot 2.1-不生成 QClasses
- reactjs - 使用 DateRangePicker 在特定月份阻止一周中的某一天
- r - 正则表达式 Tidyverse,如果存在,如何捕获表达式
- python - 为什么在 Python 3 中 NotImplemented 是真实的?
- java - 在 where 条件 - 条件中连接 2 列