Как узнать код С#, который вводит переменную с

Я хочу иметь некоторую функцию, которая возвращала бы "Base", если бы ему передавалась переменная класса Base, "Derived", если она была объявлена ​​как Derived и т.д. Не зависит от типа времени выполнения он был назначен.

Ответ 1

См., например, код ниже. Ключ состоит в использовании Generics, метод расширения использовался только для хорошего синтаксиса.

using System;

static class Program
{
    public static Type GetDeclaredType<T>(this T obj)
    {
        return typeof(T);
    }

    // Demonstrate how GetDeclaredType works
    static void Main(string[] args)
    {
        ICollection iCollection = new List<string>();
        IEnumerable iEnumerable = new List<string>();
        IList<string> iList = new List<string>();
        List<string> list = null;

        Type[] types = new Type[]{
            iCollection.GetDeclaredType(),
            iEnumerable.GetDeclaredType(),
            iList.GetDeclaredType(),
            list.GetDeclaredType()
        };

        foreach (Type t in types)
            Console.WriteLine(t.Name);
    }
}

Результат:

ICollection
IEnumerable
IList`1
List`1

EDIT: Вы также можете избежать использования метода расширения здесь, так как это приведет к появлению в раскрывающемся списке каждый IntelliSense. См. Другой пример:

using System;
using System.Collections;

static class Program
{
    public static Type GetDeclaredType<T>(T obj)
    {
        return typeof(T);
    }

    static void Main(string[] args)
    {
        ICollection iCollection = new List<string>();
        IEnumerable iEnumerable = new List<string>();

        Type[] types = new Type[]{
                GetDeclaredType(iCollection),
                GetDeclaredType(iEnumerable)
        };

        foreach (Type t in types)
            Console.WriteLine(t.Name);
    }
}

также дает правильные результаты.

Ответ 2

Это невозможно без разбора кода, о котором идет речь.

Во время выполнения доступны только две части информации типа, фактический тип значения (через object.GetType()), и, если рассматриваемая переменная является переменной параметра или класса/экземпляра, FieldType в поле FieldInfo, PropertyType в PropertyInfo или ParameterType для параметра ParameterInfo.

Так как значение, переданное вам, возможно, появилось через несколько переменных на своем пути к вам, вопрос даже не определен. Я боюсь.

Ah - я вижу, что вам нужен только тот тип, который в настоящее время определен в методе, функция Expression предоставит это (римский ответ показывает аккуратный способ сделать это), но будьте осторожны, пытаясь использовать это вне метода... В сущности вы допускаете, чтобы общий тип вывода компилятора выводил тип, о котором идет речь, но это означает, что используемая переменная не всегда является переменной, которую вы можете видеть. Это может быть вместо переменной компилятора, например:

string x = "x";
Console.WriteLine(x.GetDeclaredType()); // string
Console.WriteLine(((object)x).GetDeclaredType()); // object

Поскольку компилятор синтезирует временную переменную, в которую помещается ссылка объекта на x.

Ответ 3

Просто перезапустите GetType(), пока не нажмете объект.