简化扩展方法(组合)?

时间:2019-08-12 18:44:11

标签: c# unity3d

是否可以将扩展方法应用于两个或多个类?

本质上希望在我们有两个类的情况下清理这样的代码(不一定是混乱的)

GameObject go = new GameObject();
Transform t = new Transform();

我们希望以相同的方式对其进行操作...

GetComponentsInChildren<MeshRenderer>();

但是,如果创建了一种扩展方法,结果将是“混乱” ...

go.transform.EnableMeshRenderers(true);
t.EnableMeshRenderers(true);

到目前为止,我们的操作方式只是将扩展方法与获得所需结果所需的类型进行复制:

go.EnableMeshRenderers(true);
t.EnableMeshRenderers(true);

或者,Unity如何将GetComponent(s)方法扩展到GameObjectTransform?他们可能会通过相同的过程来这样做吗?

public static class ExtensionMethods
{
    public static void EnableMeshRenderers(this Transform trans, bool _enable, string _name = "")
    {
        foreach (MeshRenderer meshRenderer in trans.GetComponentsInChildren<MeshRenderer>())
        {
            if (string.IsNullOrWhiteSpace(_name))
                meshRenderer.enabled = _enable;
            else if (meshRenderer.gameObject.name.ToUpper().Equals(_name.ToUpper()))
                meshRenderer.enabled = _enable;
        }
    }

    public static void EnableMeshRenderers(this GameObject go, bool _enable, string _name = "")
    {
        foreach (MeshRenderer meshRenderer in go.GetComponentsInChildren<MeshRenderer>())
        {
            if (string.IsNullOrWhiteSpace(_name))
                meshRenderer.enabled = _enable;
            else if (meshRenderer.gameObject.name.ToUpper().Equals(_name.ToUpper()))
                meshRenderer.enabled = _enable;
        }
    }
}

编辑*

enter image description here

2 个答案:

答案 0 :(得分:2)

这两个功能几乎相同。它们都对MeshRenderer进行操作。唯一的区别是他们如何获得该收藏。

您可以提取公用部分,然后从两个扩展名中调用它:

public static class ExtensionMethods
{
    public static void EnableMeshRenderers(this Transform trans, bool enable, string name = "")
    {
        var renderers = trans.GetComponentsInChildren<MeshRenderer>();
        EnableMeshRenderers(renderers, enable, name);
    }

    public static void EnableMeshRenderers(this GameObject go, bool enable, string name = "")
    {
        var renderers = go.GetComponentsInChildren<MeshRenderer>();
        EnableMeshRenderers(renderers, enable, name);
    }

    public static void EnableMeshRenderers(
        this IEnumerable<MeshRenderer> meshRenderers, bool enable, string name)
    {
        foreach (MeshRenderer meshRenderer in meshRenderers)
        {
            if (string.IsNullOrWhiteSpace(name))
                meshRenderer.enabled = enable;
            else if (string.Equals(meshRenderer.gameObject.name, name, StringComparison.OrdinalIgnoreCase))
                meshRenderer.enabled = enable;
        }
    }
}

在此示例中,我也将新方法公开为公共扩展,但它可能是私有方法。

答案 1 :(得分:1)

因为它们不共享这些方法的公共接口(它们的共同祖先是UnityEngine.Object),所以不可能编写将接受任一类型参数的扩展方法。

也就是说,由于GameObject具有Transforms(反之亦然),因此可以避免两种方法的大量重复:

public static class ExtensionMethods
{
    public static void EnableMeshRenderers(this Transform trans, bool _enable, string _name = "")
    {
        foreach (MeshRenderer meshRenderer in trans.GetComponentsInChildren<MeshRenderer>())
        {
            if (string.IsNullOrWhiteSpace(_name))
                meshRenderer.enabled = _enable;
            else if (meshRenderer.gameObject.name.ToUpper().Equals(_name.ToUpper()))
                meshRenderer.enabled = _enable;
        }
    }

    public static void EnableMeshRenderers(this GameObject go, bool _enable, string _name = "") => go.transform.EnableMeshRenderers(_enable, _name);
}

反之亦然:

public static class ExtensionMethods
{
    public static void EnableMeshRenderers(this GameObject go, bool _enable, string _name = "")
    {
        foreach (MeshRenderer meshRenderer in go.GetComponentsInChildren<MeshRenderer>())
        {
            if (string.IsNullOrWhiteSpace(_name))
                meshRenderer.enabled = _enable;
            else if (meshRenderer.gameObject.name.ToUpper().Equals(_name.ToUpper()))
                meshRenderer.enabled = _enable;
        }
    }

    public static void EnableMeshRenderers(this Transform trans, bool _enable, string _name = "") => trans.gameObject.EnableMeshRenderers(_enable, _name);
}