语言支持完全反思

时间:2012-03-01 12:41:30

标签: reflection programming-languages

直到最近,我才发现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 个答案:

答案 0 :(得分:1)

关于地方变量名称的介绍性陈述引起了我的兴趣。

此代码实际上将检索lambda表达式中的本地var的名称:

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);
}

另请注意answer提及LocalVariableInfo

答案 1 :(得分:0)

是的,有些语言(至少是某种类型)可能。我想说,对于任何合理的定义,Smalltalk和Python中的反射都是非常“完整的”。

也就是说,获取局部变量的名称是毫无意义的 - 根据定义获取该变量的名称,您必须知道它的名称。我不会认为在反射设施中缺少执行该确切任务的操作。

你的第二个例子没有“确定局部变量的名称”,它检索所有局部变量的名称,这是一个不同的任务。 Python中的等效代码是:

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

答案 2 :(得分:0)

呃,为了访问本地var,你必须在stackframe / context /中本地var有效的地方。因为它只在那个时间点有效,所以它被称为't1'或'myLittlePony'是否重要?