2014-11-14 37 views
1

嘗試訪問私有(包內部)字段讓我處於一種奇怪的情況。 我的類「屬性」有一個名爲'_forceAccum'的內部字段。 試圖獲得它的價值使用此代碼對我失敗:使用鏡像訪問庫內部字段

InstanceMirror bodyMirror = reflect(props); 
var value = propsMirror.getField(new Symbol('_forceAccum')); 

,但如果我用這個來代替:

InstanceMirror bodyMirror = reflect(props); 
var value = propsMirror.getField(new Symbol('[email protected]')); 

它的工作原理。 (我從遍歷類鏡像的符號(.toString())中獲得了「@ ...」)。

它應該這樣工作嗎?它是安全的還是會在下一個版本中改變? (我正在使用1.7.2) 還是隻是純粹偶然的工作?

回答

3

你的問題是,你有一個庫私人名稱,它的名字不只是_forceAccum,這是關係到_forceAccum特殊符號所獨有的圖書館,但不同於一個_forceAccum在另一個庫。

創建使用鏡子專用符號,你必須使用MirrorSystem.getSymbol爲:MirrorSystem.getSymbol("_forceAccum", libraryMirrorOfLibrary)。這爲該特定圖書館創建了圖書館 - 私人標誌。如果沒有指定專用的庫,或者在庫中(#_forceAccum將爲其所在的庫創建正確的符號),則不能創建私有符號。

另一種選擇,你用它,是通過圖書館查閱資料,發現已經存在的符號有:

var forceAccumSymbol = 
    libraryMirrorOfLibrary.declarations.keys 
          .where((n) => MirrorSystem.getName(n) == "_forceAccum") 
          .first; 

(如果該聲明是一個頂級聲明)。

您看到的[email protected]這個名字是虛擬機使名稱庫變爲私有的方式。如果使用dart2js進行編譯,它不會起作用,並且每次運行時可能不會有相同的something,所以您不能將它放入代碼中。

2

該行爲不能保證。

如果你在同一個庫中,你可以自己構建符號(使用#_forceAccumconst Symbol("_forceAccum")new Symbol("_forceAccum"))。

去從庫外的符號,最好的辦法可能是覺得(與toString()測試,然後進行緩存。