Reflection 支持完全反射的语言

Reflection 支持完全反射的语言,reflection,programming-languages,Reflection,Programming Languages,直到最近,我才发现Java和C都不支持局部变量的反射。例如,无法在运行时检索局部变量的名称 尽管这显然是一种有意义的优化,但我很好奇当前的语言是否支持所有声明和构造的完整反映 编辑:我将进一步限定我的“局部变量名称”示例。 在C#中,可以使用反射将参数名称输出到方法: foreach(ParameterInfo pi in typeof(AClass).GetMethods()[0].GetParameters()) Trace.WriteLine(pi.Name); 您不需要知道参数

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

是的,有些语言(至少某种程度上)可以做到这一点。我想说,对于任何合理的定义,Smalltalk和Python中的反射都是相当“完整”的

也就是说,获取局部变量的名称是毫无意义的——根据定义,要获取该变量的名称,必须知道其名称。我不认为缺少一个操作来完成这项精确的任务,在反射设备中有缺陷。

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

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

你关于局部变量名称的介绍性陈述引起了我的兴趣

这段代码实际上将检索lambda表达式中本地变量的名称:

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);
}
static void Main(字符串[]args)
{
INTA=5;
表达式expr=(()=>a);
Console.WriteLine(expr.Compile().Invoke());
表达式ex=expr;
LambdaExpression lex=ex作为LambdaExpression;
MemberExpression mex=lex.Body作为MemberExpression;
Console.WriteLine(mex.Member.Name);
}

还可以看看这一点。

呃,为了访问本地var,您必须在stackframe/context/本地var有效的任何地方。由于它仅在该时间点有效,因此它是否被称为“t1”或“myLittlePony”有关系吗?

与不需要知道变量类型就可以找到其类型的方式大致相同,反射应该允许您在不知道其名称的情况下获取实例的名称。阿德尔福斯:不,你是糊涂了。名称是引用变量的方式,因此在具有类型化变量(不同于类型化值)的语言中,仍然需要变量的名称来查询其类型。这不同于拥有一个值,并且能够查询运行时系统中当前引用该值的变量列表。似乎我忽略了一个事实,即局部变量是方法体的一部分,而不是方法本身,这是有意义的。包括局部变量的反映。但是LocalVariableInfo不包含变量名,与ParameterInfo相比,这似乎是一个奇怪的例外。接下来,我将“确定局部变量的名称”改为“检索局部变量的名称”,这是您的代码示例实际执行的操作。请查看我的视频系列,从一开始就尖叫:实际变量命名确实重要,但这有点超出了我的问题范围。如果有人将所有变量命名为t1、t2、t3、t4。。那我肯定你不会高兴的!同样,如果他们在与小马无关的情况下命名变量myLittlePony!!!我想说的真正一点是,在C#和Java中,反射是不完整的,没有明显的原因。因此,不管真实世界的应用程序是什么,是否有其他语言是完全反射的。是一个关于smalltalk的视频系列。在各种各样的视频中,有很多充分反映的例子。Smalltalk之外的大多数IDE不支持完全反射,即使该语言支持。