Показ дописів із міткою .net. Показати всі дописи
Показ дописів із міткою .net. Показати всі дописи

неділя, 28 серпня 2011 р.

Mono.Cecil vs SystemReflection

Бесспорно, Mono.Cecil круче навороченее и всякое такое.
Но если небоходимо сравнить 2 метода Cecil не представляет быстрого способа это сделать.
Сесил не сохраняет информации о том, что реализация метода это просто набор байт. Есть возможность посмотреть на высокоровневые штуки под названием Opcode. Можно посмотреть на параметры опкода. Но получить набор байт представляющих метод нереально.
Приходится  делать так

var bytes = string.Join(",", method.Body.Instructions);

С другой стороны, System.Reflection.MethodInfo позволяет сделать GetILAsByteArray.
Но с ним не будет работать Cecil.Decompiler.

З.Ы. Понятное дело что исходники Mono.Cecil открыты и можно отправить туда патч. Но примут его или нет - вопрос, а плодить сущности без необходимости не хочется.

четвер, 25 серпня 2011 р.

AsmDiff unit testing

Пытаюсь добавить юнит тесты к проекту.   И обнаруживаю что не все так просто.

Тот же самый ParameterDefinition из Mono.Cecil объявлен как sealed. Это значит, что например Moq не сможет с ним работать. Придется смотреть на RhinoMock  и товарищей. Хотя что-то мне подсказывает что они тоже обломаются.
Upd. RhinoMock тоже не сумел.

Сюрпризы на этом не заканчиваются.

Например, Mono.Cecil теряет информацию о generic параметрах метода в FullString. В качестве примера


// three genrics, parameter uses generic type, return type int
        int ThreeGenericsInt<T, S, Q>(Dictionary<S, Q> dic)
превращается в 

System.Int32 CoolLibrary.Test::ThreeGenericsInt(System.Collections.Generic.Dictionary`2<S,Q>)


Если убрать generic параметр T, 

// two genrics, parameter uses generic type, return type int
        int ThreeGenericsInt<S, Q>(Dictionary<S, Q> dic)
на выходе будет то же самое

System.Int32 CoolLibrary.Test::ThreeGenericsInt(System.Collections.Generic.Dictionary`2<S,Q>)
И удобный способ заполнения Dictionary на основе method.FullName идет лесом. Конечно вопрос решаемый, но подобных мелочей выскакивает слишком уж много.

Например, считать 2 следующих определения изменением одного метода, или удалением первого, и добавлением нового?

        int ThreeGenericsInt<T, S, Q>(Dictionary<T, Dictionary<S, Q>> dic)
        int ThreeGenericsInt<T, S, Q>(Dictionary<T, Dictionary<S, Q>> dic) where T: IEnumerable
А ведь еще есть атрибуты, изменение котрых тоже стоит отслеживать, поля и свойства и всякое такое прочее.