直到最近,我才发现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)
或反映所有名称的能力是目前缺失的一个很好的功能。
答案 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'是否重要?