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 Type
s, 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 thatarguments
contains a single element that is of typeType
. It evaluates to aType
object that representsNewWord.OldWord.Class
.arguments.Single().GetType()
gets the type ofargument.Single()
. This is not the same as what typearguments.Single()
represents. It represents the typeClass
, but its type isRuntimeType
. 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 isSystem.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
How to Set Z-Order of a Control Using Winforms
Dbentityvalidationexception - How to Easily Tell What Caused the Error
Entity Framework Datetime and Utc
Unique File Identifier in Windows
Reflection - Getting the Generic Arguments from a System.Type Instance
To Underscore or to Not to Underscore, That Is the Question
Why Does It Appear That My Random Number Generator Isn't Random in C#
Wpf Application That Only Has a Tray Icon
.Net Code to Send Zpl to Zebra Printers
Understanding Wcf Windows Authentication
Remote Validation for List of Models
Converting Xdocument to Xmldocument and Vice Versa
Soap Client in .Net - References or Examples
Is There a C# Case Insensitive Equals Operator