Языки, поддерживающие полное отражение - PullRequest
0 голосов
/ 01 марта 2012

Только недавно я обнаружил, что и Java, и C # не поддерживают отображение локальных переменных. Например, вы не можете получить имена локальных переменных во время выполнения.

Несмотря на то, что эта оптимизация имеет смысл, мне любопытно, поддерживают ли текущие языки полное и полное отражение всех объявлений и конструкций.

РЕДАКТИРОВАТЬ: Я уточню мой пример "имена локальных переменных" немного дальше. В C # вы можете выводить имена параметров в методы, используя отражение:

foreach(ParameterInfo pi in typeof(AClass).GetMethods()[0].GetParameters())
    Trace.WriteLine(pi.Name);

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

foreach(LocalVariableInfo lvi in typeof(AClass).GetMethods()[0].GetLocals())
    Trace.WriteLine(lvi.Name);

Приложения могут быть ограничены (многие приложения рефлексии есть), но, тем не менее, я ожидаю, что язык с полной рефлексией будет поддерживать такую ​​конструкцию.

РЕДАКТИРОВАТЬ : Поскольку два человека теперь фактически сказали: «Нет смысла отражать имена локальных переменных», вот основной пример того, почему это полезно:

void someMethod()
{
    SomeObject x = SomeMethodCall();

    // do lots of stuff with x
    // sometime later...

    if (!x.StateIsValid)
       throw new SomeException(String.Format("{0} is not valid.", nameof(x));
}

Конечно, я мог бы просто жестко закодировать "x" в строке, но правильная поддержка рефакторинга делает это большим нет-нет. nameof(x) или возможность отображать все имена - хорошая функция, которая в настоящее время отсутствует.

Ответы [ 3 ]

1 голос
/ 01 марта 2012

Меня заинтересовало ваше вступительное заявление об именах локальных переменных.

Этот код фактически извлечет имя локальной переменной внутри лямбда-выражения:

static void Main(string[] args)
{
    int a = 5;
    Expression<Func<int>> expr = (() => a);
    Console.WriteLine(expr.Compile().Invoke());

    Expression ex = expr;
    LambdaExpression lex = ex as LambdaExpression;
    MemberExpression mex = lex.Body as MemberExpression;
    Console.WriteLine(mex.Member.Name);
}

Также естьпосмотрите на этот ответ с упоминанием LocalVariableInfo .

0 голосов
/ 01 марта 2012

эх, чтобы получить доступ к локальной переменной, вы должны находиться внутри стекового фрейма / контекста / любого другого места, где локальная переменная действительна.Поскольку он действителен только в тот момент времени, имеет ли значение, если он называется «t1» или «myLittlePony»?

0 голосов
/ 01 марта 2012

Да, есть языки, где это (по крайней мере, возможно) возможно. Я бы сказал, что отражения в Smalltalk и Python довольно «полны» для любого разумного определения.

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

Ваш второй пример не «определяет имя локальной переменной», он извлекает имя всех локальных переменных, что является другой задачей. Эквивалентный код в Python будет:

for x in locals().iterkeys(): print x
...