Getting all the Properties for a TypeDefinition

391 views
Skip to first unread message

JasonBock

unread,
Nov 5, 2008, 2:03:25 PM11/5/08
to mono-cecil
Let's say I have a TypeDefinition for a class called SubClass.
SubClass descends from BaseClass. BaseClass has a number of public
properties on it. SubClass doesn't have any. The Properties collection
for SubClass contains no values - i.e. its Count is zero. This was
unexpected - I thought Cecil would "flatten" things out and give me
those properties from BaseClass.

Is there a way to get all of the properties for a TypeDefinition, base
class(es) included (i.e. all the way up to the root)? I looked at
DeclaringType but that gives me a TypeReference which doesn't have
Properties on it.

Regards,
Jason

Lotfi Gheribi

unread,
Nov 5, 2008, 2:43:02 PM11/5/08
to mono-...@googlegroups.com
Hy,
 
Is there a way to get all of the properties for a TypeDefinition, base
class(es) included (i.e. all the way up to the root)? I looked at
DeclaringType but that gives me a TypeReference which doesn't have
Properties on it.

I don't think this is possible in Cecil. You have to browse all the parent types manually.
Remember that the parent type can be in another assembly.

Jb Evain

unread,
Nov 5, 2008, 2:55:22 PM11/5/08
to mono-...@googlegroups.com
Hey Jason,

The issue here is that Cecil's type system is quite different from the
System.Reflection one. Because in System.Reflection all referenced
assemblies have to be loaded, there's no distinction between a
reference and a definition.

Cecil does this distinction. So it could be that the .BaseType of a
TypeDefinition is a TypeReference, which of course, doesn't have any
information but its name and scope.

What we do usually is use something to Resolve a TypeReference into a
TypeDefinition, to better analyze it.

Such a resolver will make it into the next version of Cecil, but for
the time being, people are usually using the one I wrote for the
linker, which is available here:

http://anonsvn.mono-project.com/viewvc/trunk/mcs/tools/linker/Mono.Linker/AssemblyResolver.cs?revision=HEAD&content-type=text%2Fplain

So by walking down the inheritance chain, and resolving the
references, you'll be able to collect all inherited properties.

--
Jb Evain <j...@nurv.fr>

JasonBock

unread,
Nov 5, 2008, 2:57:14 PM11/5/08
to mono-cecil
Yeah, I wrote a method:

private static List<PropertyDefinition> GetProperties(this
TypeDefinition @this)
{
var properties = new List<PropertyDefinition>(
from PropertyDefinition property in @this.Properties
select property);

if(@this.BaseType != @this.Module.Import(typeof(object)))
{
var baseTypeAssembly = (new
DefaultAssemblyResolver()).Resolve(@this.BaseType.Scope as
AssemblyNameReference);
properties.AddRange(

baseTypeAssembly.MainModule.Types[@this.BaseType.FullName].GetProperties());
}

return properties;
}


which works...but the problem now is that all of the properties are
PropertyDefinitions, and their getters and setters are
MethodDefintions, which is true...but if the base type comes from
another assembly, that's not technically true. I ended up getting all
sorts of [ERROR: INVALID TOKEN] things showing up in ILDasm because
there is no method defintion in the current assembly.

JasonBock

unread,
Nov 5, 2008, 3:10:18 PM11/5/08
to mono-cecil
...snip...

> which works...but the problem now is that all of the properties are
> PropertyDefinitions, and their getters and setters are
> MethodDefintions, which is true...but if the base type comes from
> another assembly, that's not technically true. I ended up getting all
> sorts of [ERROR: INVALID TOKEN] things showing up in ILDasm because
> there is no method defintion in the current assembly.

Just fixed that by doing this:

propertyGetter.DeclaringType.Module.Assembly !=
@this.Module.Assembly ?
@this.Module.Import(propertyGetter) : propertyGetter
Reply all
Reply to author
Forward
0 new messages