如何重构此代码(C#,Types)

时间:2017-03-06 15:15:16

标签: c# unity3d types game-engine

首先,我对问题的标题道歉。我不太确定我想要完成的是什么,所以我只是直截了当。

我目前正在使用GDI +在c#中开发一个游戏引擎并实现了一个组件类。这个想法是任何游戏对象都可以附加多个组件(很像Unity3D),我想通过搜索它是什么类来找到任何类型的任何组件。

就此而言,我想改变这段代码:

Rigidbody r = obj.GetComponentOfType(typeof(Rigidbody)) as Rigidbody;

看起来像这样:

Rigidbody r = obj.GetComponentOfType<Rigidbody>();

我该怎么做?

对不起,如果我的问题看起来很模糊,那么关于这个话题的任何亮点都会很棒!

8 个答案:

答案 0 :(得分:6)

这称为通用方法。您可以创建一个重载,调用现有的基于类型的实现,如下所示:

public T GetComponentOfType<T>()
{
    return (T) GetComponentOfType(typeof(T));
}

答案 1 :(得分:3)

假设您的obj类型中有List<Component>字段。您可以使用Linq

// assuming
public class GameObject
{
    List<Component> m_Components; // all components attached to this GameObject
    public TComponent GetComponentOfType<TComponent>()
        where TComponent : Component
    {
        // Select only the ones of type TComponent and return first one
        return m_Components.OfType<TComponent>().FirstOrDefault();
    }
}

要使用此功能:obj.GetComponentOfType<Rigidbody>();

答案 2 :(得分:1)

如果您无法更改课程,可以使用扩展方法:

public static T GetComponentOfType<T>(this [objType] obj)
where T : class
{
    return obj.GetComponentOfType(typeof(T)) as T;
}

答案 3 :(得分:1)

我认为您希望实现如下通用方法:

using System.Linq;
using System.Collections.Generic;

/// <summary>
/// Base-Class
/// </summary>
public abstract class Thing
{
    private ICollection<Thing> _things;

    public Thing()
    {
        _things = new List<Thing>();
    }

    public void AddSomething(Thing toAdd)
    {
        _things.Add(toAdd);
    }

    /// <summary>
    /// Assuming that every type can only appear once
    /// </summary>
    /// <param name="t"></param>
    /// <returns></returns>
    public T GetComonentOfType<T>() where T : Thing
    {
        return this.GetComonentOfType(typeof(T)) as T;
    }

    public Thing GetComonentOfType(Type t)
    {
        return _things.Where(x => x.GetType() == t).Single();
    }

}

/// <summary>
/// One possible implementation
/// </summary>
public class SpecialThing : Thing
{

}

答案 4 :(得分:0)

为GetComponentOfType方法添加一个扩展方法,该方法为您执行脏工作(您发布的第一行代码)并让它接受泛型类型。然后,您可以在&lt;&gt;中传入Rigidbody类型标签

有关扩展方法的详细信息,请转到here

编辑:确保您的扩展方法是静态的。

希望它有所帮助。

答案 5 :(得分:0)

这是通过使用泛型来完成的。 GetComponentofType方法的主体几乎相同,唯一的区别是您通过泛型指定了所需的类型,而不是将其作为参数传递。

该方法可能如下所示:

 public T GetComponentOfType<T>(){

      //code goes here to locate the object.
      you can get the type via typeof(T) 

      return theObject;
 }

答案 6 :(得分:0)

&#13;
&#13;
   public class Rigidbody{
        public int Size{ get; set; }
        public string fourgroundColor{ get; set; }
        public string backgroundColor{ get; set; }
        public int fingerammount{ get; set; }
        public int arms{ get; set; }
    }
&#13;
&#13;
&#13;

创建一个名为Rigidbody的类。将所有组件设置为类,而不是使用它。 Olso公开,否则你不能像你的例子一样使用它。

当你有这个课时你可以说:var r = obj.GetComponentOfType(); olso使用var而不是数据类型。 var更好的数据类型是oldscool(更像是c#1或C2.0)我每次都做同样的错误。但当我开始作为软件开发人员工作时,他们告诉我使用var(我仍然只是一个初级,最好的medior)

答案 7 :(得分:0)

假设所有组件类都继承了这个类(或类似的):

public abstract class IComponent
{
    protected IList<object> objComponents;

    public object GetComponentOfType(Type type)
    {
        if (objComponents == null)
            return null;

        return objComponents.Where(obj => obj.GetType() == type).FirstOrDefault();
    }
}

你可以创建另一个主要的母类来继承自:

public abstract class BaseComponent : IComponent
{
    public object GetComponentOfType<T>()
    {
        return GetComponentOfType(typeof(T));
    }
}

或者,如果您有权访问第一个类,只需添加上一个函数即可。