【问题标题】:How to approach refactoring this code (C#, Types)如何重构此代码(C#,类型)
【发布时间】:2017-07-26 12:44:07
【问题描述】:

首先,对于问题的标题,我深表歉意。我不太确定我想要完成的任务叫什么,所以我会直奔主题。

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

在此说明,我想更改这段代码:

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

改为这样:

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

我该怎么做?

对不起,如果我的问题看起来含糊不清,任何关于这个话题的线索都会很棒!

【问题讨论】:

标签: c# unity3d types game-engine


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    假设您的 obj 类型中有一个 List&lt;Component&gt; 字段。你可以使用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&lt;Rigidbody&gt;();

    【讨论】:

      【解决方案3】:

      我认为你想实现一个通用方法,如下所示:

      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】:

        如果不能改类,可以使用扩展方法:

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

        【讨论】:

          【解决方案5】:

          向 GetComponentOfType 方法添加一个扩展方法,该方法为您完成繁琐的工作(您发布的第一行代码)并让它接受泛型类型。然后你可以在 标签中传入 Rigidbody 类型。

          有关扩展方法的更多信息,请访问here

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

          希望对你有帮助。

          【讨论】:

            【解决方案6】:

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

            该方法可能如下所示:

             public T GetComponentOfType<T>(){
            
                  //code goes here to locate the object.
                  you can get the type via typeof(T) 
            
                  return theObject;
             }
            

            【讨论】:

              【解决方案7】:

                 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; }
                  }

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

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

              【讨论】:

              • IMO 这个答案完全没有意义。 OP 询问了如何创建一个通用方法来提取他的组件,而您正在编写有关编译时类型解析方法的文章。
              【解决方案8】:

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

              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));
                  }
              }
              

              或者如果你可以访问第一个类,只需将前面的函数添加到它。

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2019-06-07
                • 1970-01-01
                • 2023-03-07
                • 2010-09-08
                • 1970-01-01
                相关资源
                最近更新 更多