C# 循环调用问题解决(interface方案)

写代码都会要求高密度,低耦合,尽量避免循环引用的出现。曾经面试时,有一道面试题是这样的,如果A引用B,B引用C,C又引用A,怎么解决这种循环引用?如图:

这也是今天写这个的原因,个人思路为把环状拆分为一条直线,也就是让A持有B,B持有C,而把C要调用的A中的内容抽离出来,这里把这部分叫做D,通过B,把D传递给C。也就是C持有的,实际上不再是A,而是A里的一部分C需要的内容(D)。如图:

当然这里所给的,只是一种思路,因为根据实际问题,如果ABC三者处于同级,那再让A持有B,B持有C就不合适了,也需要只暴露某一部分公共的内容。比如玩家攻击敌人,玩家和敌人属于同级,可能只需要执行一个敌人掉血的函数,而却把整个敌人类暴露给玩家类,就很不合适了。这里不做赘述,具体要根据不同环境进一步规划该怎么写,这里只提供思路。

公共部分D,以什么形式传递,就是下面要写的内容,有两种方式,委托和接口。下面重点说接口的方式。这里提供一个别人写的博客:讲到了解决循环引用的第三种方式,反射。

https://blog.csdn.net/ZslLoveMiwa/article/details/80813568

本文只写接口方式,委托比较简单,同样可以用写一个更复杂点的事件系统去做处理。代码如下:

ClassA

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public interface MethodA
{
    void MethodA();
    
}

public class ClassA : MonoBehaviour, MethodA
{
   
    private ClassB m_claasB;

    void Start () {
        m_claasB = new ClassB(this);
    }

    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.A))
        {
            CCallA();
        }

        if (Input.GetKeyDown(KeyCode.B))
        {
            ACallB();
        }

        if (Input.GetKeyDown(KeyCode.C))
        {
            BCallC();
        }
    }

    public void MethodA()
    {
       Debug.Log("Class A__MethodA"); 
    }

    public void CCallA()
    {
        m_claasB.CCallA();
    }

    public void BCallC()
    {
        m_claasB.BCallC();
    }

    public void ACallB()
    {
        m_claasB.MethodB();
    }


}

ClassB:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;



public class ClassB 
{

    private ClassC m_classC;

    public ClassB(MethodA actionA)
    {
        m_classC=new ClassC(actionA);
    }

    public void MethodB()
    {
       Debug.Log("ClassB_MethodB");
    }

    public void BCallC()
    {
        m_classC.MethodC();
    }

    public void CCallA()
    {
        m_classC.CallA();
    }

}

ClassC:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;



public class ClassC : MonoBehaviour
{

    private MethodA _methodA;
	// Use this for initialization
	public ClassC(MethodA ActionA )
	{
	    _methodA = ActionA;

	}
	
    public void MethodC()
    {
       Debug.Log("ClassC _MethodC");
    }

    public void CallA()
    {
        _methodA.MethodA();
    }
}

其实不管是委托,还是接口,其目的都是只暴露给其他类需要调用的部分,尽可能少的暴露不必要的内容给其他类。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值