Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Kotlin equivalent of C# events

Tags:

c#

events

kotlin

I am new in Kotlin and was trying to find any equivalent in Kotlin for C# events. I couldn't find any examples so I suppose there aren't any events in Kotlin. Am I right? And also how this functionality in C# can be done in Kotlin?

class A
{
    public event Action<int> NormalEvent;
    public static event Action<int> StaticEvent;

    public void FunA(int x)
    {
        NormalEvent?.Invoke(x);
        StaticEvent?.Invoke(x);

    }
}

class B
{
    private readonly A aInstance;

    public void FunBNormal(int x)
    {
        Console.WriteLine($"Normal event {x}");
    }

    public void FunBStatic(int x)
    {
        Console.WriteLine($"Static event {x}");
    }

    public B(A a)
    {
        aInstance = a;
        aInstance.NormalEvent += FunBNormal;
        A.StaticEvent += FunBStatic;
    }
}
like image 218
iknow Avatar asked Jun 09 '20 18:06

iknow


People also ask

Is kotlin C based?

 Kotlin is inspired by existing languages such as Java, C#, JavaScript, Scala and Groovy.

Can Kotlin call C++?

Kotlin can call C/C++ code with any type of data or object. We found out a lot of theoretical material and based on it created the sample project. We converted Java Strings inside the native code, passed Kotlin objects to the native code, called functions and threw Exceptions of Java.

Is C++ like Kotlin?

C++ and Kotlin can be categorized as "Languages" tools. "Performance" is the top reason why over 146 developers like C++, while over 28 developers mention "Interoperable with Java" as the leading cause for choosing Kotlin.

Is Kotlin native or hybrid?

Kotlin Multiplatform Mobile is an SDK for iOS and Android app development. It offers all the combined benefits of creating cross-platform and native apps. It is trusted in production by many of the world's leading companies, including Philips, Netflix, Leroy Merlin, and VMWare.

What is type conversion in Kotlin?

Type conversion (also called as Type casting) refers to changing the entity of one data type variable into another data type. As we know Java supports implicit type conversion from smaller to larger data type. An integer value can be assigned to long data type. But, Kotlin does not support implicit type conversion.

How do I map between C and Kotlin?

The best way to understand the mapping between Kotlin and C is to try a tiny example. We will declare a struct and a union in the C language, to see how they are mapped into Kotlin. Kotlin/Native comes with the cinterop tool, the tool generates bindings between the C language and Kotlin. It uses a .def file to specify a C library to import.

What is the difference between C struct and Union in Kotlin?

Technically, there is no difference between struct and union types on the Kotlin side. Note that a, b, and c properties of MyUnion class in Kotlin use the same memory location to read/write their value just like union does in C language. It is easy to use the generated wrapper classes for C struct and union types from Kotlin.

What are the types of equality in Kotlin?

In Kotlin there are two types of equality: Structural equality (== - a check for equals ()) Referential equality (=== - two references point to the same object)


2 Answers

There isn't a built-in language construct for this, but it would be rather trivial to create a class for it. Maybe it would take a little more work to make it thread-safe and avoid leaking listeners. It depends on your needs.

class Event<T> {
    private val observers = mutableSetOf<(T) -> Unit>()

    operator fun plusAssign(observer: (T) -> Unit) {
        observers.add(observer)
    }

    operator fun minusAssign(observer: (T) -> Unit) {
        observers.remove(observer)
    }

    operator fun invoke(value: T) {
        for (observer in observers)
            observer(value)
    }
}
class A {
    companion object {
        val staticEvent = Event<Int>()
    }
    val normalEvent = Event<Int>()

    fun funA(x: Int) {
        normalEvent(x)
        staticEvent(x)
    }
}

class B(private val aInstance: A) {
    init {
        aInstance.normalEvent += ::funBNormal
        A.staticEvent += ::funBStatic
    }

    fun funBNormal(x: Int) {
        println("Normal event $x")
    }


    fun funBStatic(x: Int) {
        println("Static event $x")
    }
}
like image 139
Tenfour04 Avatar answered Sep 29 '22 09:09

Tenfour04


You can use Signals for this. It uses a proxy magic to turn an interface into a Signal object. It holds on listeners and fire events.

fun interface Chat{
    fun onNewMessage(s:String)    
}

class Foo{
    val chatSignal = Signals.signal(Chat::class)
    
    fun bar(){
        chatSignal.addListener { s-> Log.d("chat", s) } // logs all the messaged to Logcat
    }
}

class Foo2{
    val chatSignal = Signals.signal(Chat::class)
    
    fun bar2(){
        chatSignal.dispatcher.onNewMessage("Hello from Foo2") // dispatches "Hello from Foo2" message to all the listeners
    }
}

The equivalent for static and normal events in your example will be

  • Signal.signal() - creates a singleton Signal object
  • Signal.localSignal() - creates a new instance of a Signal object

Disclaimer: I am the author of Signals.

like image 40
Ilya Gazman Avatar answered Sep 29 '22 09:09

Ilya Gazman