C# 基于参数';类型';

C# 基于参数';类型';,c#,unity3d,C#,Unity3d,我想创建一个战略游戏。当我点击操作栏中的“BuildHouse”按钮时,我希望我的经理注册应该建造的建筑 我的所有建筑都是构件,因此我尝试将建筑类型作为参数传入 我的按钮执行 public void BuildFarm() { buildManager.SetBuilding(typeof(Farm)); // Farm is a child of Building } 现在,BuildManager知道了建筑的类型。我试着遍历所有的建筑预制件,选择一个与类型匹配的 public cl

我想创建一个战略游戏。当我点击操作栏中的“BuildHouse”按钮时,我希望我的经理注册应该建造的建筑

我的所有建筑都是构件,因此我尝试将建筑类型作为参数传入

我的按钮执行

public void BuildFarm()
{
    buildManager.SetBuilding(typeof(Farm)); // Farm is a child of Building
}
现在,
BuildManager
知道了建筑的类型。我试着遍历所有的建筑预制件,选择一个与类型匹配的

public class BuildManager : MonoBehaviour
{
    [SerializeField]
    private GameObject[] buildings;

    public void SetBuilding(Type buildingType)
    {
        GameObject targetBuilding = buildings.Where(currentBuilding => buildingType == currentBuilding.GetComponent<Building>().GetType()).First();
    }
}
公共类BuildManager:MonoBehavior
{
[序列化字段]
私人游戏对象[]建筑;
公共建筑(类型buildingType)
{
GameObject targetBuilding=buildings.Where(currentBuilding=>buildingType==currentBuilding.GetComponent().GetType()).First();
}
}

我不知道是否有更好的方法让
BuildManager
知道要构建什么。如果这个想法不好,请提供更好的实现方法。

我建议定义一个
enum

enum BuildingType
{
    Farm,
    House,
    ...
}
然后可以为
建筑
定义
类型
属性:

public class Building
{
    ...
    BuildingType Type { get; set; }
    ... 
}
然后您可以像这样调用
SetBuilding
(可能使用
开关
):


我建议定义一个
enum

enum BuildingType
{
    Farm,
    House,
    ...
}
然后可以为
建筑
定义
类型
属性:

public class Building
{
    ...
    BuildingType Type { get; set; }
    ... 
}
然后您可以像这样调用
SetBuilding
(可能使用
开关
):


在我看来,按组件类型过滤是绝对好的。如果您有
农场
房屋
组件,并且它们都是建筑,那么自然可以用继承层次结构来表示

关于使用
enum
:enum最擅长表示不太可能更改的简单状态或指定良好的值,例如。一周中不会有第八天,对吗?另一方面,您可能希望自由扩展可用建筑的列表,并且每个建筑可能实现不同的游戏逻辑。更自然的表达方式是创建类层次结构。当类就位时,为同一事物添加
enum
是多余的

也就是说,我建议对代码进行一些改进

    public void SetBuilding<TBuilding>() where TBuilding : IBuilding
    {
        GameObject targetBuilding = buildings
           .Where(currentBuilding => 
              typeof(TBuilding) == currentBuilding.GetComponent<Building>().GetType())
           .SingleOrDefault();

        if(targetBuilding == null)
        {
           // throw or log an error here
        }
        else
        {
           // instantiate
        }
    }
public void SetBuilding(),其中TBuilding:i生成
{
GameObject targetBuilding=建筑物
.其中(currentBuilding=>
typeof(TBuilding)=currentBuilding.GetComponent().GetType())
.SingleOrDefault();
如果(targetBuilding==null)
{
//在此处抛出或记录错误
}
其他的
{
//实例化
}
}
  • 如果编译时总是知道
    buildingType
    ,则可以使用泛型。它使对该方法的调用更具可读性:
    buildManager.SetBuilding()

  • 请注意
    中的TBuilding:i生成约束。使您的
    农场
    房屋
    类实现一个公共接口
    IBuilding
    (它也可以是一个公共基类):
    类农场:组件,IBuilding
    。通过这种方式,编译器可以确保您不能调用类似
    buildManager.SetBuilding()的东西


  • SingleOrDefault
    确保只有一次这样的尝试。如果没有或超过1,则返回null。如果是这种情况,抛出或记录错误。我知道您正在确保
    建筑物
    数组是正确的,但您应该使用代码强制执行它


  • 在我看来,按组件类型过滤是绝对好的。如果您有
    农场
    房屋
    组件,并且它们都是建筑,那么自然可以用继承层次结构来表示

    关于使用
    enum
    :enum最擅长表示不太可能更改的简单状态或指定良好的值,例如。一周中不会有第八天,对吗?另一方面,您可能希望自由扩展可用建筑的列表,并且每个建筑可能实现不同的游戏逻辑。更自然的表达方式是创建类层次结构。当类就位时,为同一事物添加
    enum
    是多余的

    也就是说,我建议对代码进行一些改进

        public void SetBuilding<TBuilding>() where TBuilding : IBuilding
        {
            GameObject targetBuilding = buildings
               .Where(currentBuilding => 
                  typeof(TBuilding) == currentBuilding.GetComponent<Building>().GetType())
               .SingleOrDefault();
    
            if(targetBuilding == null)
            {
               // throw or log an error here
            }
            else
            {
               // instantiate
            }
        }
    
    public void SetBuilding(),其中TBuilding:i生成
    {
    GameObject targetBuilding=建筑物
    .其中(currentBuilding=>
    typeof(TBuilding)=currentBuilding.GetComponent().GetType())
    .SingleOrDefault();
    如果(targetBuilding==null)
    {
    //在此处抛出或记录错误
    }
    其他的
    {
    //实例化
    }
    }
    
  • 如果编译时总是知道
    buildingType
    ,则可以使用泛型。它使对该方法的调用更具可读性:
    buildManager.SetBuilding()

  • 请注意
    中的TBuilding:i生成约束。使您的
    农场
    房屋
    类实现一个公共接口
    IBuilding
    (它也可以是一个公共基类):
    类农场:组件,IBuilding
    。通过这种方式,编译器可以确保您不能调用类似
    buildManager.SetBuilding()的东西


  • SingleOrDefault
    确保只有一次这样的尝试。如果没有或超过1,则返回null。如果是这种情况,抛出或记录错误。我知道您正在确保
    建筑物
    数组是正确的,但您应该使用代码强制执行它


  • 为什么不使用
    enum
    作为建筑类型而不是构件?因为无论如何,我必须将其与建筑的构件进行比较
    buildings
    数组是具有不同类型的构件吗?这是预制的吗?你能发布你的建筑类型构件吗?
    建筑
    是一组预制件。这些预制件包含类型为
    Building
    的构件。目前,我有两个组件来自<