Yan Cui
I help clients go faster for less using serverless technologies.
For a while now I’ve been wondering why C#’s support for covariance does not cover value types, both in normal array covariance and covariance in the generic parameter introduced in C# 4:
1: void Main()
2: {
3: int i = 0;
4: string str = "hello world";
5:
6: TestMethod(i); // legal
7: TestMethod(str); // legal
8: TestMethod2(Enumerable.Empty<int>()); // illegal
9: TestMethod2(Enumerable.Empty<string>()); // legal
10:
11: Console.WriteLine(i is object); // true
12: Console.WriteLine(new int[0] is object[]); // false
13: Console.WriteLine(new string[0] is object[]); // true
14: Console.WriteLine(new uint[0] is int[]); // false
15: }
16:
17: public void TestMethod(object obj)
18: {
19: Console.WriteLine(obj);
20: }
21:
22: public void TestMethod2(IEnumerable<object> objs)
23: {
24: Console.WriteLine(objs.Count());
25: }
Until I stumbled upon this old post by Eric Lippert on the topic of array covariance, which essentially points to a disagreement in the C# and CLI specification on the rule of array covariance:
CLI
"if X is assignment compatible with Y then X[] is assignment compatible with Y[]"
C#
"if X is a reference type implicitly convertible to reference type Y then X[] is implicitly convertible to Y[]"
Whilst this doesn’t directly point to the generics case with IEnumerable<out T>, one would expect they are one and the same, otherwise you end up with different rules for int[] and IEnumerable<int> where (new int[0] is IEnumerable<int>) == true.. now that would be weird!
References:
Eric Lippert – Why is covariance of value-typed arrays inconsistent?
Question on StackOverflow – why does my C# array lose type sign information when cast to object?
Whenever you’re ready, here are 3 ways I can help you:
- Production-Ready Serverless: Join 20+ AWS Heroes & Community Builders and 1000+ other students in levelling up your serverless game. This is your one-stop shop for quickly levelling up your serverless skills.
- I help clients launch product ideas, improve their development processes and upskill their teams. If you’d like to work together, then let’s get in touch.
- Join my community on Discord, ask questions, and join the discussion on all things AWS and Serverless.