-1

I'm trying to understand:

Object obj = "string";
var type = obj.GetType(); // returns System.String 

I know this is a successful implicit conversion but I don't understand why if obj.GetType() is called it returns System.String and not System.Object.

If i'd want to have a string type, I would not have assigned "string" to an Object type. It would be more correct if obj will remain a Object type. Can anyone explain?

Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179
  • 1
    `GetType()` returns the runtime type of the object, which is always `string` from start to finish. If you want to get the type of the variable, just hover over it and write `typeof(object)` (or whatever you want). [Each one has its use](http://stackoverflow.com/a/983061/1892179). – Theodoros Chatzigiannakis Apr 22 '17 at 15:42
  • Also you may want to read on https://www.bing.com/search?q=c%23+convert+vs+cast. – Alexei Levenkov Apr 22 '17 at 16:47

3 Answers3

2

You have a string literal and its type is string. When you assign it to obj variable which is an object, string literal is implicitly converted to object, this is valid because all class types implicitly inherits from object.

So you have an object but the underlying type of the object that obj is referring to is still string. By converting it to objectyou are only making it so that compiler will treat obj as object, not string. Because of this, for example you can't call methods declared on string type using obj.

obj.GetType() returns the underlying type, not the type you converted your object into. That is why you are getting string and not object.

Selman Genç
  • 100,147
  • 13
  • 119
  • 184
  • 1
    "When you assign it to obj variable which is an object, string literal is implicitly converted to object". That is not true, the string literal isn't converted to anything. The reference is. – InBetween Apr 22 '17 at 18:15
0

Because its a reference conversion. As the name implies, in a reference conversion, the only thing that changes is the reference, AKA the variable pointing to the object.

The bits that make up the string literal "string" don't change, the only thing you are doing in Object o = "string" is creating a variable o typed Object that points to the the string "string". The value stored in the variable o is precisely the address in memory where that string is:

Given:

var s = "Hello";

Any of these conversions are reference conversions:

object o = s; //creates a new reference typed object pointing to "Hello".
IComparable<string> e = s; //creates a new reference tpyed...

o.GetType() and e.GetType() will both return System.String because o and e both point to exactly the same object: "Hello".

Now this isn't the only conversion that can happen. There are tons of conversions that are not reference conversions or identity preserving conversions. An example? All user defined conversions (implicit or explicit operator):

int i = 1;
double d = i;
d.GetType() //returns Double.

Why? Because i and d are two different objects, the bits that make up an integer and a double are completely different. The implicit cast from int to double is a user defined operator:

class Bar
{
    public Bar(Foo f) { ... }
}

class Foo
{
    public static implicit operator Bar(Foo f) => new Bar(f);
}

Now if you do:

var f = new Foo();
object o = f;
Bar b = f; //implicit user defined conversion from Foo to Bar

You will get the following outputs:

o.GetType() //Reference conversion: returns Foo
b.GetType() //User defined conversion: returns Bar

Do note that all reference conversions are provided by the compiler, you can't define a reference conversion as a user defined operator:

public static implicit operator Object(Foo f) { ... } //compile time error. 

All that said, there is one special non identity preserving conversion where GetType() will still return the type of the original object. Can you tell me which one it is?

Also, reference conversions involving value types are not possible, precisely because a value type variable's value is not a reference, it's the value type instance itself.

InBetween
  • 32,319
  • 3
  • 50
  • 90
-1

Actually, as everything in C# inherits from object, everything is an object. For example the string type derives from object (Take a look at this for more information: Value types inherit from System.Object...why?). That means, every string is an object - and can therefore implicitly be converted to an object. However, it still remains a string - it is just treated as an object.

The string actually remains in it's core still a string, even if you try to cast it to an object - this is the same for every inheriting item. For example, if you have the following code:

public class Class2 : Class1
{

}

public class Class1
{

}

And execute the following code somewhere else (I used the interactive)

((Class1)new Class2()).GetType()

You'd still get Class2 as a result.

Actually, I don't think it's possible to do so - you can always pretend that it is of another type, and I don't see any reason why this shouldn't be sufficient.

Community
  • 1
  • 1
MetaColon
  • 2,895
  • 3
  • 16
  • 38