共享属性而不继承

时间:2017-05-10 17:20:55

标签: c# unity3d

我正在使用引擎Unity,几乎所有脚本的基类都必须从MonoBehaviour派生。我创建了自己的包装类,它来自MonoBehaviour,名为CMonoBehaviour,它包含了我几乎无处不在的一些辅助函数。但是现在我遇到了问题,有时候我不想从MonoBehavuour派生出来但是ThirtPartyLibraryWrapperClass(类,也是从MonoBehaviour派生出来的,但也实现了一些附加的功能 - 就像我的包装一样)。以下是我要存档的示例。

编辑:我忘了提到ThirtPartyLibraryWrapperClass是用dll打包的,这意味着我无法以任何方式修改它

 // This is what I have
public class CMonoBehavour : MonoBehaviour
{
    public int SomeHelperProperty1 { get; private set; }
    public int SomeHelperProperty2 { get; private set; }
    public int SomeHelperProperty3 { get; private set; }
    public int SomeHelperProperty4 { get; private set; }
}

public class ThirtPartyLibraryWrapperClass : MonoBehaviour
{
    public int SomeHelperProperty5 { get; private set; }
    public int SomeHelperProperty6 { get; private set; }
}

// My problem :

public class ExampleUseage1 : CMonoBehavour
{
    // here I have to copypaste content of ThirtPartyLibraryWrapperClass because I cust cannot derive from two classes
}

public class ExampleUseage2 : ThirtPartyLibraryWrapperClass
{
    // here I have to copypaste content of CMonoBehavour because I cust cannot derive from two classes
}

3 个答案:

答案 0 :(得分:3)

您可能想重新考虑您的架构。 您似乎过度依赖继承来提供功能。

有很多方法可以重构您的方法,例如:

  • 使用扩展方法提供功能(界面扩展方法是一个好主意)
  • 使用构图
  • 使用接口+ composition =>您可以将组合包装在重新实现的属性中,这些属性只会将调用传递给内部对象。

复合/包装解决方案:

    public class CMonoBehavour : MonoBehaviour
    {
        public int SomeHelperProperty1 { get; private set; }
        public int SomeHelperProperty2 { get; private set; }
        public int SomeHelperProperty3 { get; private set; }
        public int SomeHelperProperty4 { get; private set; }
    }

    public class ThirtPartyLibraryWrapperClass : MonoBehaviour
    {
        public int SomeHelperProperty5 { get; private set; }
        public int SomeHelperProperty6 { get; private set; }
    }

    //COMPOSITE SOLUTION

    public class CompositeMonoBehaviour : CMonoBehaviour
    {
        private ThirtPartyLibraryWrapperClass _thirdParty;

        public int SomeHelperProperty5 { get{ return _thirdParty.SomeHelperProperty5; } }
        public int SomeHelperProperty6 { get{ return _thirdParty.SomeHelperProperty6; } }
    }

    public class ExampleUseage1 : CompositeMonoBehaviour
    {
          //you have all your properties, great news!
    }

    public class ExampleUseage2 : CompositeMonoBehaviour
    {
        //you have all your properties, great news!
    }

请记住,Unity有一个实体组件系统,它是GameObject设计的核心。过度继承是:

  • 一般的糟糕设计
  • 打击框架,这是徒劳的练习

答案 1 :(得分:1)

您可以执行部分​​继承并仅共享所需的属性。这样的事情:

public class CMonoBehavour : MonoBehaviour
{
    public int SomeHelperProperty1 { get; private set; }
    public int SomeHelperProperty2 { get; private set; }
    public int SomeHelperProperty3 { get; private set; }
    public int SomeHelperProperty4 { get; private set; }
}

public class ThirtPartyLibraryWrapperClass : CMonoBehavour
{
    public int SomeHelperProperty5 { get; private set; }
    public int SomeHelperProperty6 { get; private set; }
}


//The first class have 4 properties
public class ExampleUseage1 : CMonoBehavour
{

}
    //The first class have 6 properties
public class ExampleUseage2 : ThirtPartyLibraryWrapperClass
{

}

答案 2 :(得分:-1)

Interface Magic

CMonoBehavour(呃,CMonoBehaviour,因为"行为"中的i应该是接口这种情况。

public interface CMonoBehaviour
{
    int SomeHelperProperty1 { get; }
    int SomeHelperProperty2 { get; }
    int SomeHelperProperty3 { get; }
    int SomeHelperProperty4 { get; }
}

请注意,虽然没有定义set,但实现私有集的接口实现者完全合法。该界面只是所有 public 属性和方法的列表。

e.g:

public class Something : MonoBehaviour,CMonoBehaviour
{
    private int a;
    public int SomeHelperProperty1 {
        get {
            return a;
        }

        private set  {
            a = value;
        }
    }
    ...
}

虽然现在它是一个界面,但我们应该重命名它以表明:IMonoBehaviour或可能IBehaviourExtensionsIBehaviourAdditionsIBaseBehaviour。命名它" MonoBehaviour"对于这个类/接口的用途或用途是什么并不是很有帮助或指示。