Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C#/.NET - why is string[] castable to object[] but int[] is not? [duplicate]

Tags:

c#

clr

I encountered with question: why it's impossible cast int[] to object[] , e.g. object[] o = new int[] { 0, 1, 2 };

Meanwhile I can cast to just object and back to int[].

I'll be glad to hear deep answer.

like image 467
Maxim Gorokhovich Avatar asked Mar 05 '14 23:03

Maxim Gorokhovich


People also ask

What C is used for?

C programming language is a machine-independent programming language that is mainly used to create many types of applications and operating systems such as Windows, and other complicated programs such as the Oracle database, Git, Python interpreter, and games and is considered a programming foundation in the process of ...

What is the full name of C?

In the real sense it has no meaning or full form. It was developed by Dennis Ritchie and Ken Thompson at AT&T bell Lab. First, they used to call it as B language then later they made some improvement into it and renamed it as C and its superscript as C++ which was invented by Dr.

Is C language easy?

C is a general-purpose language that most programmers learn before moving on to more complex languages. From Unix and Windows to Tic Tac Toe and Photoshop, several of the most commonly used applications today have been built on C. It is easy to learn because: A simple syntax with only 32 keywords.

What is C in C language?

What is C? C is a general-purpose programming language created by Dennis Ritchie at the Bell Laboratories in 1972. It is a very popular language, despite being old. C is strongly associated with UNIX, as it was developed to write the UNIX operating system.


2 Answers

Directly from the docs:

Array covariance specifically does not extend to arrays of value-types. For example, no conversion exists that permits an int[] to be treated as an object[].

An array of ints or any other value-type is not an array of objects. Value types have different storage characteristics to those of reference types. An array of (reference type) objects holds a list of object references (with the objects themselves living in the heap), so the slots will always be a constant width. Value types, on the other hand, store their value directly in the array, so the slots might be any width. This makes a conversion between the two meaningless.

It's a little confusing because even though value-types are derived from System.Object, they behave very differently to reference types, and object-like behaviour of value types (e.g. boxing) is only possible through magical handling of them by the compiler and runtime, and it doesn't extend to arrays.

As a side note, casting arrays is a well dodgy practice. I wouldn't do it.

like image 174
spender Avatar answered Oct 04 '22 05:10

spender


For an instance of type A to be castable to type B, one of the following conditions must be true:

  1. there is an implicit/explicit conversion from A to B;
  2. there is a hierarchical relationship. Such a relationship could be achieve through one of two ways:
    1. deriving A from B (e.g., class A : B {})
    2. covariance/contravariance. C# allows covariance for:
      1. arrays of reference types (string[] > object[]) (*)
      2. generic types arguments in interfaces/delegates (IEnumerable<string> > IEnumerable<object> and Func<string> > Func<object>)
      3. delegates ( string Method() {} can be assigned to delegate object Del(); )

You cannot cast int[] to object[] because none of the above conditions are true.


(*) - You should avoid this though - array covariance is broken and was it was added simply so that the CLR would support Java-like languages.

like image 40
dcastro Avatar answered Oct 04 '22 06:10

dcastro