On 24.05.2010 12:16, Jb Evain wrote:
> It's not really hard, to compare two type references, you can first
> compare its namespace and its name. If they're not equal, the types
> are different. If they're equal, you need to compare their assembly.
> If the Scope is a ModuleDefinition, then you compare its
> module.Assembly.Name.FullName, if it's an AssemblyNameReference, you
> can just use its FullName.
>   
That's only a rough approximation.
In .NET 4 due to the [TypeForwardedTo]-attribute, two types can be equal
even if they are in different assemblies (for example, the delegate
System.Action in System.Core, version=3.5.0.0 is considered the same
type as System.Action in mscorlib, version=4.0.0.0).
Also, two assemblies with the same simple name but different versions
may or may not be equal depending on runtime policies (version
redirection etc.).
In general, a static analysis tool such as Mono.Cecil can never be sure
whether two types are equal.

Some possible solutions:
1) Only use Namespace+Type Name: you'll have lots of false positives
(almost all BCL assemblies share internal classes in the internal MS.*
namespaces)
2) Use Namespace+Type Name+Simple Assembly Name: you'll have both false
positives (rare, only if app loads different versions of the same
assembly) and false negatives (redirected types)
3) Use Namespace+Type Name+Full Assembly Name: you'll have false
negatives (redirected types + assemblies redirected to another version)

I think best would be 2), maybe you could also add some special code to
detect [TypeForwardedTo].
Note that both redirected types and redirected assembly versions are
commonly used (e.g. when using .NET 2.0 or 3.x assemblies in a .NET 4.0
app).

Daniel

Attachment: signature.asc
Description: OpenPGP digital signature

Reply via email to