3

I need to call the following function :

static string GetValueOrDefault(object[] values, int index)
{
    if (values == null)
         return string.Empty;
    if (index >= values.Length)
         return string.Empty;
    return values[index] != null ? values[index].ToString() : string.Empty;
}

When I call GetValueOrDefault with an array of strings (ReferenceType), it works :

GetValueOrDefault(new[] {"foo", "bar"}, 0);

When I call GetValueOrDefault with an array of int (ValueType), it doesn't work :

GetValueOrDefault(new[] {1, 2}, 0);

The compiler error is :

The best overloaded method match for MyNamespace.GetValueOrDefault(object[], int)' has some invalid arguments

So my question is : Why this doesn't compile as reference types and value type derive from object ?

I know I can solve this problem using generics, but I want to understand this error

static string GetValueOrDefault<T>(T[] values, int index)
{...}

Thanks in advance

Community
  • 1
  • 1
AlexH
  • 2,650
  • 1
  • 27
  • 35

1 Answers1

6

Arrays of reference-types are covariant, meaning: a string[] can be treated as an object[] (although the gotcha is that if you try to put a non-string in, it will throw). However, arrays of value-types are not covariant, so an int[] cannot be treated as an object[]. new[] {1,2} is an int[].

IIRC this was done mainly for similarity with java. The covariance in .NET 4.0 is much tidier.

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • Very interesting, didn't know that was the case. – Levi Botelho Jan 29 '13 at 12:49
  • 2
    Thanks for the answer, I've just found an Eric's article speaking about that : http://blogs.msdn.com/b/ericlippert/archive/2007/10/17/covariance-and-contravariance-in-c-part-two-array-covariance.aspx – AlexH Jan 29 '13 at 12:49