What's the Difference Between System.Type and System.Runtimetype in C#

What's the difference between System.Type and System.RuntimeType in C#?

System.RuntimeType is a concrete class that derives from the abstract base class System.Type. Since System.RuntimeType is not public, you will typically encounter instances of it as System.Type.

Confusion can arise when you are trying to get the type of an object and mistakenly call GetType() on another object representing the first object's type, rather than just using that object directly. Then Type.ToString() will return "System.RuntimeType" when the object it is called on is representing a Type:

string str = string.Empty;
Type strType = str.GetType();
Type strTypeType = strType.GetType();
strType.ToString(); // returns "System.string"
strTypeType.ToString(); // returns "System.RuntimeType"

For example, in this blog post someone is trying to get the type of a column in a database, doing something like this:

object val = reader.GetFieldType(index);
Type runtimeType = val.GetType();
PropertyInfo propInfo = runtimeType.GetProperty("UnderlyingSystemType");
Type type = (Type)propInfo.GetValue(val, null);

Since val is already a Type object, val.GetType() will return another Type object representing the type System.RuntimeTime as this is the concrete type used to represent the original type object. The blog post then shows some unnecessary reflection trickery, to get the type of the original type object, when really all that was required was:

Type type = reader.GetFieldType(index) as Type;

So if your Type object is reporting that it represents a System.RuntimeType, make sure you have not accidentally called GetType() on a type you have already got.

Whats the difference between RuntimeTypeHandle and Type?

Caution: This answer appears to be out of date. It was posted before .NET 4 became available, which apparently introduced some optimizations regarding Type and thus rendered the information in this answer obsolete. See this more recent answer for details.

According to this blog post (from 2006) by Vance Morrison, RuntimeTypeHandle is a value type (struct) that wraps an unmanaged pointer, so Type.GetTypeHandle(obj).Equals(anotherHandle) is faster to use for strict "is exactly the same type" comparisons than obj.GetType().Equals(anotherType) — the latter creates System.Type instances which are, apparently, heavier.

However, it's also less obvious, and definitely falls under the category "micro-optimization" so if you're wondering when you need one over the other, you should probably just use System.Type.

What's the different between (Type) and Get.Type()

This is going to get really meta...

Assuming your arguments is actually an array of Types, the expression (Type)arguments.Single() makes the compile-time type of the single argument become Type.

The type Type represents a type. In this case, you got NewWorld.OldWorld.Class, which most likely is the fully qualified name of a class. The single element in arguments (which is of type Type) represents the type NewWord.OldWorld.Class.

The second expression in question, arguments.Single().GetType() gets the runtime type of the object on which GetType is called, as an instance of Type. In this case, This will return the runtime type of arguments.Single(), which is RuntimeType, a subclass of Type.

Basically:

  • (Type)arguments.Single() tells the compiler that arguments contains a single element that is of type Type. It evaluates to a Type object that represents NewWord.OldWord.Class.

  • arguments.Single().GetType() gets the type of argument.Single(). This is not the same as what type arguments.Single() represents. It represents the type Class, but its type is RuntimeType. If you are still confused, here's an example with integers.

    int[] array = new int[] { 10 };

    array.Single() represents the number 10 but its type is System.Int32.

How to determine if a Type is of RunTimeType?

I guess that you actually want to know if a Type object describes the Type class, but the Type object is typeof(RuntimeType) and not typeof(Type) and so comparing it to typeof(Type) fails.

What you can do is check if a instance of the type described by the Type object could be assigned to a variable of type Type. This gives the desired result, because RuntimeType derives from Type:

private bool IsTypeOfType(Type type)
{
return typeof(Type).IsAssignableFrom(type);
}

If you really need to know the Type object that describes the Type class, you can use the GetType Method:

private bool IsRuntimeType(Type type)
{
return type == typeof(Type).GetType();
}

However, because typeof(Type) != typeof(Type).GetType(), you should avoid this.


Examples:

IsTypeOfType(typeof(Type))                          // true
IsTypeOfType(typeof(Type).GetType()) // true
IsTypeOfType(typeof(string)) // false
IsTypeOfType(typeof(int)) // false

IsRuntimeType(typeof(Type)) // false
IsRuntimeType(typeof(Type).GetType()) // true
IsRuntimeType(typeof(string)) // false
IsRuntimeType(typeof(int)) // false

GetType from object is returning RuntimeType

If you call it like this -

string a = "";
string type = getType(a);

It will return System.String

But if you call like this -

string a = "";
string type = getType(a.GetType());

Then it will return System.RuntimeType

Also, there is small typo in your method -

Type type = obj.getType(); should be Type type = obj.GetType();

Do all Type classes inherit from RuntimeType?

OK, I think the entire question reduces to

How can I determine that a field is of type Type?

As far as I can tell you don't care about the actual type of the values stored there because you will serialize all of them the same way ("then I can simply serialize them as strings using Type.AssemblyQualifiedName").

Here you go:

bool IsType(Type type)
{
return type == typeof(Type);
}

No need for a subclass check. The actual objects will be of a subclass but the field will have type Type.

You can add the subclass check if you like:

bool IsType(Type type)
{
return typeof(Type).IsAssignableFrom(type);
}

How does c# System.Type Type have a name property

Notice that System.Type is itself an abstract class. That means it can be overriden in a subclass. In fact, you can see that types at run-time are not actually System.Type's if you do something like this:

typeof(Type).GetType().FullName; // System.RuntimeType

The System.RuntimeType is an internal type that you won't see in the documentation, but it does override the Name property. It looks a little like this:

namespace System
{
internal class RuntimeType : Type, ISerializable, ICloneable
{
...
public override string Name
{
get { ... }
}
}
}

See this note in the official documentation:

Type is an abstract base class that allows multiple implementations. The system will always provide the derived class RuntimeType. In reflection, all classes beginning with the word Runtime are created only once per object in the system and support comparison operations.

System.RuntimeType doesn't contain a definition for Declared Properties

DeclaredProperties is a member of System.TypeInfo, not of System.Type and least of all dyanmic.

Thus simply write this instead:

Type dt = typeof(T);
if (dT.Name.EndsWith("List"))
dT = dT.GetTypeInfo().DeclaredProperties.First().PropertyType.GenericTypeArguments[0];

I strongly recommend not to use dyanmic unless you really need it (which isn´t the case here). Dynamic will only shift the actual error (in your case access to a member that doesn´t exist) to runtime instead of to the compiler which makes it harder to find errors. Another reason here is that you already know the runtime-type of the expression typeof(T), which is allways System.Type. Why should you want to hide this information by using dynamic?



Related Topics



Leave a reply



Submit