2014-11-14 9 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

Поведение не гарантируется.

Если вы были в той же библиотеке, вы можете, вероятно, создать символ самостоятельно (либо с #_forceAccum, либо с const Symbol("_forceAccum") или new Symbol("_forceAccum")).

Лучший способ добраться до символа из-за пределов его библиотеки, вероятно, найти его (тестирование с toString() и кэширует его.

Смежные вопросы