1

I want to know whether a on object of type Type is actually a type for a normal class (e.g. Object, Int32, etc.) or a type for a meta-object (e.g. typeof(Object), typeof(Int32), etc.).

By type of an object I mean:

Type t = typeof(Object);
Console.WriteLine("Type is {0}", t.FullName);

Type is System.Object

And by type of a type object, i.e. meta-object:

Type t = typeof(Object).GetType();
Console.WriteLine("Type is {0}", t.FullName);

Type is System.RuntimeType

I couldn't find any method/property in Type or TypeInfo to tell whether the object for which a Type object is made is actually a Type rather than a normal object.

If I have the object, I could do that:

bool IsType(object o) { return o is Type; }

But, I don't have the object itself, only its type.

I was hoping for something along the lines:

bool IsType(Type t) { return t.GetTypeInfo().IsType; }

But there's nothing like it, it seems..

So the only thing I can think of so far is:

bool IsType(Type type)
{
    // Can't use typeof(RuntimeType) due to its protection level
    Type runtimeType = typeof(Object).GetType();
    return runtimeType.Equals(type);
}

Yet, I can't be sure that GetType() for all objects of type Type would return RuntimeType, nor that they actually inherit from it...

Update

Let me explain it better. I'm writing a serializer. When serializing a class member (e.g. a field or a property), I'll have the field type (yet not the object). It's perfectly possible the member to be of type Type. I'd like to be able to serialize those objects as well.

For example a class like so:

class MyClass {
    private Type _cachedType;
}

I'll get the Type of the field _cachedType through reflection. How will I know that the object is a Type in the first place?

Albus Dumbledore
  • 12,368
  • 23
  • 64
  • 105
  • Why do you care? RuntimeType is an implementation detail of the current version of the .NET Framework. – usr Oct 24 '15 at 11:05
  • 1
    Possible duplicate of [What's the difference between System.Type and System.RuntimeType in C#?](http://stackoverflow.com/questions/5737840/whats-the-difference-between-system-type-and-system-runtimetype-in-c) | [GetType from object is returning RuntimeType](http://stackoverflow.com/questions/12997946/gettype-from-object-is-returning-runtimetype) – Bjørn-Roger Kringsjå Oct 24 '15 at 11:06
  • `How will I know that the object is a Type in the first place?` well, it clearly is because the variable is typed `Type`. Why don't you serialize _cachedType.FullName or something like that? Why do you need to know the exact object type? – usr Oct 24 '15 at 17:05
  • @usr, because I have serializers for different types. Depending on the type of the field, you'd be serializing it in a different way, *obviously*. – Albus Dumbledore Oct 24 '15 at 17:19
  • How will you serialize a `RuntimeType` differently from any other `Type` (e.g. a `TypeBuilder`)? There aren't many meaningful derived classes of `Type`. I don't know of any that would matter. – usr Oct 24 '15 at 17:21
  • Maybe I misunderstood the question? Do you want to know how to identify fields that are of type `Type`? – usr Oct 24 '15 at 17:24
  • @usr. Precisely. If they are of type `Type`, then I can simply serialize them as strings using `Type.AssemblyQualifiedName`, and deserialize them with the same string using `Type.GetType()`. – Albus Dumbledore Oct 24 '15 at 17:31

2 Answers2

1

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);
}
usr
  • 168,620
  • 35
  • 240
  • 369
  • Directly, comparing with `typeof(Type)` is so simple, I didn't think of it. Thanks. Meanwhile, I forgot to mention that it's for a portable library, I'd have to use `TypeInfo` rather than `Type` for `IsAssignableFrom`. – Albus Dumbledore Oct 24 '15 at 18:04
  • Unfortunately, the direct comparison doesn't appear to work for me, because `typeof(Type)` appears to return `Type`, while, Object.GetType() for an object of type `Type` returns `RuntimeType`... See here for what I mean: http://volatileread.com/utilitylibrary/snippetcompiler?id=38352 – Albus Dumbledore Oct 24 '15 at 18:31
  • 1
    Yeah, you need to use the field type which is FieldInfo.FieldType. If you have to use the object type then use the IsAssignableFrom check. – usr Oct 24 '15 at 18:45
0

I think I got it. I could use TypeInfo.IsAssignableFrom.

bool IsType(Type type)
{
    TypeInfo info = typeof(Type).GetTypeInfo();
    return info.IsAssignableFrom(type.GetTypeInfo());
}

Which is roughly the equivalent of using the is operator on an object, but this type it's a runtime type.

Albus Dumbledore
  • 12,368
  • 23
  • 64
  • 105