See the question and my original answer on StackOverflow

Yes, it works as it should.

Here is a .NET Core 3.1 or .NET 5 COM class (follow more or less this tutorial and register: Exposing .NET Core components to COM):

namespace ClassLibrary1
{
    [ComVisible(true)]
    [Guid("f39feec6-dd52-4da3-967a-c1e67de9346d")]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    public interface IServer
    {
        void ComputePi();
        double GetComputedPi();
    }

    [ComVisible(true)]
    [Guid("5ff4acc2-2faa-4ea3-bae9-8c90fa67d75b")]
    [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)] // this is marked obsolete in .NET Core 3.1 but not any more in .NET 5
    public interface IServerEvents
    {
        [DispId(1234)]
        void OnPiComputed();
    }

    [ComVisible(true)]
    [ClassInterface(ClassInterfaceType.None)]
    [ComSourceInterfaces(typeof(IServerEvents))] // this is marked obsolete in .NET Core 3.1 but not any more in .NET 5
    [Guid("32c58b14-b6fb-41f5-8368-52dc9289ae19")]
    public class Server : IServer
    {
        private event OnPiComputedEvent OnPiComputed;

        public delegate void OnPiComputedEvent();

        public void ComputePi()
        {
            Console.WriteLine("PI is being computed...");
            OnPiComputed?.Invoke();
        }

        public double GetComputedPi() => Math.PI;
    }
}

And for example, a .NET Framework COM client (interface are redefined exactly the same but you could create a common type library/.TLB or share a .cs):

class Program
{
    static void Main()
    {
        var type = Type.GetTypeFromCLSID(new Guid("32c58b14-b6fb-41f5-8368-52dc9289ae19"));
        var obj = (IServer)Activator.CreateInstance(type);

        var container = (IConnectionPointContainer)obj;
        var iid = typeof(IServerEvents).GUID;
        container.FindConnectionPoint(ref iid, out var point);
        
        var sink = new ServerEvents();
        point.Advise(sink, out var cookie);
        
        obj.ComputePi();
        Console.ReadKey(true);

        point.Unadvise(cookie);
    }
}

public class ServerEvents : IServerEvents
{
    public void OnPiComputed()
    {
        Console.WriteLine("PI was computed!");
    }
}

[ComVisible(true)]
[Guid("f39feec6-dd52-4da3-967a-c1e67de9346d")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IServer
{
    void ComputePi();
    double GetComputedPi();
}

[ComVisible(true)]
[Guid("5ff4acc2-2faa-4ea3-bae9-8c90fa67d75b")]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface IServerEvents
{
    [DispId(1234)]
    void OnPiComputed();
}

When ran, it should display:

PI is being computed...
PI was computed!