I wonder why IEnumerable<int>
can't be assigned to a IEnumerable<object>
. After all IEnumerable
is one of the few interfaces that supports covariance...
int
seems to be a proper subtype of object
The combination of both features doesn't work however...
class A
{
}
class B : A
{
}
class Program
{
static void Main(string[] args)
{
bool b;
b = typeof(IEnumerable<A>).IsAssignableFrom(typeof(List<B>));
Console.WriteLine("ienumerable of ref types is covariant: " + b); //true
b = typeof(IEnumerable<object>).IsAssignableFrom(typeof(List<int>));
Console.WriteLine("ienumerable of value tpyes is covariant: " + b); //false
b = typeof(object).IsAssignableFrom(typeof(int));
Console.WriteLine("int is a subtype of object: " + b); //true
}
}
thanks for your help! sebastian
Meskipun C dibuat untuk memprogram sistem dan jaringan komputer namun bahasa ini juga sering digunakan dalam mengembangkan software aplikasi. C juga banyak dipakai oleh berbagai jenis platform sistem operasi dan arsitektur komputer, bahkan terdapat beberepa compiler yang sangat populer telah tersedia.
C adalah huruf ketiga dalam alfabet Latin. Dalam bahasa Indonesia, huruf ini disebut ce (dibaca [tʃe]).
Bahasa pemrograman C ini dikembangkan antara tahun 1969 – 1972 oleh Dennis Ritchie. Yang kemudian dipakai untuk menulis ulang sistem operasi UNIX. Selain untuk mengembangkan UNIX, bahasa C juga dirilis sebagai bahasa pemrograman umum.
Value types aren't LSP-subtypes of object until they're boxed.
Variance doesn't work with value types. At all.
Demonstration that int
is not a proper subtype (subtype in the LSP sense) of object
:
Works:
object x = new object();
lock (x) { ... }
Does not work (substitutability violated):
int y = new int();
lock (y) { ... }
Returns true:
object x = new object();
object a = x;
object b = x;
return ReferenceEquals(a, b);
Returns false (substitutability violated):
int y = new int();
object a = y;
object b = y;
return ReferenceEquals(a, b);
Of course, the topic of the question (interface variance) is a third demonstration.
The problem is that object
is a reference type, not a value type. The only reason you can assign an int
to a variable of type object
is boxing.
In order to assign List<int>
to IEnumerable<object>
you'd have to box each element of the list. You can't do that just by assigning the reference to the list and calling it a different type.
The simplistic answer is that this is just one of the quirks in the way that variance is implemented in C# and the CLR.
From "Covariance and Contravariance in Generics":
Variance applies only to reference types; if you specify a value type for a variant type parameter, that type parameter is invariant for the resulting constructed type.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With