将数组从一种类型转换为另一种类型

时间:2016-02-02 19:33:24

标签: c# unity3d

我想将一个碰撞器数组转换为一个GameObjects数组。这是我知道如何做到这一点的唯一方法,但它并不是最佳的。有更好的方法吗?

GameObject[] GetOverLap(){
    GameObject[] gameObjects;
    Collider[] colliders = Physics.OverlapSphere(transform.position, radius, layer);
    gameObjects = new GameObject[colliders.Length];
    for(int i = 0; i < colliders.Length; i++){
        gameObjects[i] = colliders[i].gameObject;
    }
    return gameObjects;
}

以下是完整的代码块:

protected GameObject[] GetOverLap(GameType gameType){
    GameObject[] gameObjects = null;
    if(gameType == GameType._3D){
        Collider[] colliders = Physics.OverlapSphere(transform.position, radius, layer);
        gameObjects = new GameObject[colliders.Length];
        for(int i = 0; i < colliders.Length; i++){
            gameObjects[i] = colliders[i].gameObject;
        }
    }else if(gameType == GameType._2D){
        Collider2D[] colliders = Physics2D.OverlapCircleAll(transform.position, radius, layer);
        gameObjects = new GameObject[colliders.Length];
        for(int i = 0; i < colliders.Length; i++){
            gameObjects[i] = colliders[i].gameObject;
        }
    }
    return gameObjects;
}

这是重复的,无论如何都要压缩它,因为if / else中唯一不同的行是OverlapSphere/OverlapCircleAll

4 个答案:

答案 0 :(得分:1)

使用Array.ConvertAll。这个看起来很干净。

有关msdn。

的完整文档here

答案 1 :(得分:0)

简而言之,我建议使用automapper框架。 因为,基本上你正在做的是将一个类/对象映射到另一个类

映射将消除主代码的复杂性,并简化语法。因此,它看起来类似于:

GameObject[] gameObjects = null;
if (gameType == GameType._3D){    
     gameObjects = Mapper.Map<Collider, GameObject>(colliders); }

else if(gameType == GameType._2D) {
    gameObjects = Mapper.Map<Collider2D, GameObject> (colliders); };

基本上,您将在公共映射器文件中实现所有映射逻辑。 默认情况下,当每个对象中的属性名称和类型相同时,automapper会执行属性映射:

mapper.CreateMap<Collider, GameObject>();
mapper.CreateMap<Collider2D, GameObject>();

如果属性名称或类型不同,则需要定义单个映射。快速示例看起来像以下代码段:

mapper.CreateMap<Collider, GameObject>()
      .ForMember(dest => dest.Prop1, opt => opt.Ignore())
      .ForMember(dest => dest.StateName, opt => opt.MapFrom(src => src.StateProvinceName));
       .ForMember(dest => dest.Prop2, opt => opt.Ignore());

和Collider2D分别为:

mapper.CreateMap<Collider2D, GameObject>()
         .ForMember(dest => dest.Id, opt => opt.MapFrom(src => src.StaffId))
         .ForMember(dest => dest.PersonName, opt => opt.MapFrom(src => src.StaffName));

答案 2 :(得分:0)

或者你可以使用Linq。

Response.AddHeader "Set-Cookie", _
                   RFC6265CookieValue( _
                     "cookiename",  _
                     "size=big&flavor=chocolate+chip" _
                     DateAdd("yyyy", 1, Now()), domain), _
                     "example.com"

我通常更喜欢将Lists over Arrays用于一般用途 - 我喜欢他们的方法而不是Arrays可用的方法。无论如何,我希望这段代码有助于提高您的可读性。

我希望有所帮助!

<强>更新 更新了代码,感谢@DRapp的建议。

答案 3 :(得分:0)

您可以使用委托,因为两种方法都获得相同的签名:

protected GameObject[] GetOverLap(float radius, int layer, 
    Func<Vector3, float,int,Collider[]> action){
    GameObject[] gameObjects = null;
        Collider[] colliders = action(transform.position, radius, layer);
        gameObjects = new GameObject[colliders.Length];
        for(int i = 0; i < colliders.Length; i++){
            gameObjects[i] = colliders[i].gameObject;
        }
    return gameObjects;
}

你走了:

GameObject [] objs = GetOverlap(5f, myLayer, Physics.OverlapSphere);
GameObject [] objs = GetOverlap(5f, myLayer, Physics2D.OverlapCircleAll);