2012-03-01 73 views
0

直到最近,我發現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)); 
} 

當然,我可能只是硬編碼「× 「在字符串中,但正確的重構支持使得這是一個很大的禁忌。或者反映所有姓名的能力是當前缺失的一個很好的功能。

+0

我已經改變了「確定一個局部變量的名字」來「檢索局部變量的名字」,這就是你的代碼實例所做的事情。 – Marcin 2012-03-01 13:49:22

+0

請從一開始就看看我的視頻系列,Squeak:http://www.youtube.com/playlist?list = PL6601A198DF14788D&feature = view_all – Saijanai 2012-03-04 02:19:37

回答

0

是的,有些語言是可以的(至少是種類的)。我會說在Smalltalk和Python中的反射對於任何合理的定義都非常「完整」。

這就是說,獲取局部變量的名稱是非常沒有意義的 - 根據定義獲取變量的名稱,您必須知道它的名稱。我不會考慮缺乏一個操作來完成這個確切的任務在反射設施中的一個缺陷。

你的第二個例子沒有「確定一個局部變量的名字」,它檢索了所有局部變量的名字,這是一個不同的任務。 Python中的等效代碼爲:

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

與您不需要知道變量類型以找出其類型的方式大致相同,反射應該允許您在不知道名稱的情況下獲取實例的名稱。理論上。 – adelphus 2012-03-01 13:13:14

+0

@adelphus:不,你很困惑。名字就是你如何引用這個變量,所以在一個帶有類型變量的語言中(與類型化的值不同),你仍然需要變量的名字來查詢它的類型。這與具有值不同,並且能夠查詢運行時系統以獲取當前引用該值的變量列表。 – Marcin 2012-03-01 13:21:08

1

您對本地變量名稱的介紹性聲明引起了我的興趣。

此代碼將實際檢索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); 
} 

也有看看這個answerLocalVariableInfo

+0

看來,我錯過了局部變量是方法體的一部分,而不是方法本身,這是有道理的。包括局部變量的反映。但是LocalVariableInfo不包含與ParameterInfo相比似乎是一個奇怪異常的變量名稱。繼續... – adelphus 2012-03-01 13:38:03

0

呃,爲了訪問一個局部變量,你必須在棧幀/上下文/無論哪裏局部變量有效。既然它只是在那個時候纔有效,那麼稱它爲't1'還是'myLittlePony'它有什麼關係?

+0

實際變量命名確實很重要,但對於我的問題有點超出範圍。如果有人將他們的所有變量命名爲t1,t2,t3,t4 ..那麼我相信你會不高興!同樣,如果他們在與小馬無關時將變量命名爲myLittlePony! – adelphus 2012-03-02 10:39:53

+0

我試圖做的真正的一點是,C#和Java中的反射並不完整,沒有明顯的原因。因此,無論現實世界的應用程序如何,其他語言是否完全反思。 – adelphus 2012-03-02 10:43:22

+0

http://www.youtube.com/playlist?list=PL6601A198DF14788D&feature=view_all是一個關於smalltalk的視頻系列。在各種視頻中有很多充分反思的例子。即使語言不支持,Smalltalk之外的大多數IDE都不支持全面反射。 – Saijanai 2012-03-04 02:21:26