In Kotlin, you can have this with generics:
class Foo<T> {
fun toto(arg: Bar<in T>) {}
fun tata(arg: Baz<out T>) {}
}
What is the equivalent in C#?
I tried to replicate the code in C# like this
class Foo<T> {
public void toto(Bar<in T> arg) {}
public void tata(Baz<out T> arg) {}
}
I expected for it to work, but it says Type argument is missing.
C# does not have use-site variance - it only allows you to specify the variance at the declaration (which you can also do in Kotlin), and only for interface types. e.g.
One way to "simulate" use-site variance is to divide up your class into "things that you can use covariantly" (
Tin an output position) and "things that you can use contravariantly" (Tin an input position). Declare an interface for each of those two groups, with the correct variance.Then you can use
ICovariantBar<T>forBar<out T>in Kotlin,IContravariantBar<T>forBar<in T>in Kotlin. For example,totowould be declared like this:This of course has a few caveats. From the top of my head:
Bar<T>int. In Kotlin you can assign an instance ofBar<Int>to aBar<out Any>, butBar<int>is not convertible to aIConvariantBar<object>.Tin an input position whenTis covariant, and methods withTin an output position whenTis contravariant. It's just that the typeTwould be replaced byNothing(the "bottom type") or the bound ofTrespectively. You'd need to add some extra methods in order to do the same in C#