views:

117

answers:

2
using System;

interface IAnimal
{
}

class Cat: IAnimal
{
}

class Program
{
    public static void Main(string[] args)
    {
        IAnimal cat = new Cat();

        // Console.WriteLine(cat.GetType());
           // This would only give me the type of 
           // the backing store, i.e. Cat. Is there a 
           // way I can get to know that the identifier 
           // cat was declared as IAnimal?

        Console.ReadKey();
    }
}

Update: Thanks to Dan Bryant for the reminder.

using System;
using System.Reflection;
using System.Collections.Generic;
using System.Linq;

namespace TypeInfo
{
    class Program
    {
        public static void Main(string[] args)
        {
            IAnimal myCat = new Cat();
            ReflectOnType();
            Console.ReadKey();
        }

        public static void ReflectOnType()
        {
            Assembly.GetExecutingAssembly().
                GetType("TypeInfo.Program").
                GetMethod("Main", 
                BindingFlags.Static| BindingFlags.Public).
                GetMethodBody().LocalVariables.
                ToList().
                ForEach( l => Console.WriteLine(l.LocalType));
        }
    }

    interface IAnimal { }
    class Cat : IAnimal { }
}
A: 

Per suggestion above, I'm posting this as an answer. See the comments above for further context.


You indicated that you're still seeing the 'backing store' with LocalVariableInfo. What this suggests to me is that the declaration is purely in the source and not actually encoded in the method at all. The fact that you chose to use an interface as the 'declared' type is irrelevant, as the compiler chose to use the more specific type for the local variable slot. Try running ILdasm on your DLL output and you can see if this is true. If it is, your only option is to actually look at the source code, since the information literally doesn't exist in the compiled version.

Dan Bryant
I stand corrected. I wasn't. While I'd written the code to use LocalVariableInfo.LocalType, I was, err, not even calling the code. My calling code still had Console.WriteLine(obj.GetType()).
Water Cooler v2
+1  A: 

You can use generic type inference:

using System;

internal interface IAnimal
{
}

internal class Cat : IAnimal
{
}

class Program
{
    static void Main()
    {
        var cat = new Cat();
        Console.WriteLine(cat.GetType()); // Cat
        Console.WriteLine(GetStaticType(cat)); // Cat

        IAnimal animal = cat;
        Console.WriteLine(GetStaticType(animal)); // IAnimal
    }

    static Type GetStaticType<T>(T _)
    {
        return typeof (T);
    }
}
desco