MessageBrokerでBaseClassやInterfaceのイベントを受け取る

using System;
using Cysharp.Threading.Tasks;
using Extensions;
using UnityEngine;

public class MessageTest : MonoBehaviour
{
    public void Start() => Test().Forget();

    private async UniTask Test()
    {
        var messageBroker = new TaskMessageBroker();

        messageBroker.Subscribe<TestMessage>(x =>
        {
            Debug.Log("Receive TestMessage");
            return UniTask.CompletedTask;
        });

        messageBroker.Subscribe<ITestMessageInterface>(x =>
        {
            Debug.Log("Receive ITestMessageInterface"); // こっちが呼ばれる
            return UniTask.CompletedTask;
        });

        ITestMessageInterface a = new TestMessage();
        await messageBroker.PublishAsync(a);
    }
}

public interface ITestMessageInterface
{
}

public class TestMessage : ITestMessageInterface
{
}

こうするとITestMessageInterfaceの方が呼ばれてしまいます。

using System;
using Cysharp.Threading.Tasks;
using Extensions;
using UnityEngine;

public class MessageTest : MonoBehaviour
{
    public void Start() => Test().Forget();

    private async UniTask Test()
    {
        var messageBroker = new TaskMessageBroker();

        messageBroker.Subscribe<TestMessage, ITestMessageInterface>(x =>
        {
            Debug.Log("Receive TestMessage");
            return UniTask.CompletedTask;
        });

        ITestMessageInterface a = new TestMessage();
        await messageBroker.PublishAsync(a);
    }
}

public static class TaskMessageBrokerExtensions
{
    public static IDisposable Subscribe<T1, T2>(this TaskMessageBroker self, Func<T1, UniTask> asyncMessageReceiver) where T1 : T2
    {
        return self.Subscribe<T2>(x =>
        {
            if (x is T1 t) return asyncMessageReceiver(t);
            return UniTask.CompletedTask;
        });
    }
}

public interface ITestMessageInterface
{
}

public class TestMessage : ITestMessageInterface
{
}

こんな感じのExtensionを書いてSubscribe側で工夫してあげましょう。