TypeLoadException

Hello -
I recently added code I adapted from C# to C++ based on an articale on CodeProject.com that is used to provide runtime Properties to a PropertyGrid. The link is:
http://www.codeproject.com/cs/miscctrl/bending_property.asp?#xxxx
It now compiles fine, but I get the runtime error TypeLoadException with the message: "Body referenced in a method implementation must be defined in the same type" along with the name of the assmebly and other assmebly info. I'm baffled as to what this could mean. Any help would be appreciated. I will paste in the code for the class at the end of this post. Thanks in advance -
Samy

// forward declare all header files needed by this class
#include "ModifiableOwnerOwned.h"

// include namespaces used
using namespace System;
using namespace System::Collections;
using namespace System::ComponentModel;
using namespace System::Drawing::Design;
using namespace System::Runtime::Serialization;
namespace AEM
{
namespace Shared
{
// Class: PropertySpec
// Description: Represents a single property in a PropertySpec.
public __gc class PropertySpec
{
// [Constructors]
public:
PropertySpec(String* name, String* type)
{ Initialize( name, type, NULL, NULL, NULL, NULL, NULL );}
PropertySpec(String* name, Type* type)
{ Initialize( name, type->AssemblyQualifiedName, NULL, NULL, NULL, NULL, NULL );}
PropertySpec(String* name, String* type, String* category)
{ Initialize( name, type, category, NULL, NULL, NULL, NULL );}
PropertySpec(String* name, Type* type, String* category)
{ Initialize( name, type->AssemblyQualifiedName, category, NULL, NULL, NULL, NULL );}
PropertySpec(String* name, String* type, String* category, String* description)
{ Initialize( name, type, category, description, NULL, NULL, NULL );}
PropertySpec(String* name, Type* type, String* category, String* description)
{ Initialize( name, type->AssemblyQualifiedName, category, description, NULL, NULL, NULL );}
PropertySpec(String* name, String* type, String* category, String* description, Object* defaultValue)
{ Initialize( name, type, category, description, defaultValue, NULL, NULL );}
PropertySpec(String* name, Type* type, String* category, String* description, Object* defaultValue)
{ Initialize( name, type->AssemblyQualifiedName, category, description, defaultValue, NULL, NULL );}
PropertySpec(String* name, String* type, String* category, String* description, Object* defaultValue,
String* editor, String* typeConverter)
{ Initialize( name, type, category, description, defaultValue, editor, typeConverter );}
PropertySpec(String* name, Type* type, String* category, String* description, Object* defaultValue,
String* editor, String* typeConverter)
{ Initialize( name, type->AssemblyQualifiedName, category, description, defaultValue, editor, typeConverter );}
PropertySpec(String* name, String* type, String* category, String* description, Object* defaultValue,
Type* editor, String* typeConverter)
{ Initialize( name, type, category, description, defaultValue, editor->AssemblyQualifiedName, typeConverter );}
PropertySpec(String* name, Type* type, String* category, String* description, Object* defaultValue,
Type* editor, String* typeConverter)
{ Initialize( name, type->AssemblyQualifiedName, category, description, defaultValue, editor->AssemblyQualifiedName, typeConverter );}
PropertySpec(String* name, String* type, String* category, String* description, Object* defaultValue,
String* editor, Type* typeConverter)
{ Initialize( name, type, category, description, defaultValue, editor, typeConverter->AssemblyQualifiedName );}
PropertySpec(String* name, Type* type, String* category, String* description, Object* defaultValue,
String* editor, Type* typeConverter)
{ Initialize( name, type->AssemblyQualifiedName, category, description, defaultValue, editor, typeConverter->AssemblyQualifiedName );}
PropertySpec(String* name, String* type, String* category, String* description, Object* defaultValue,
Type* editor, Type* typeConverter)
{ Initialize( name, type, category, description, defaultValue, editor->AssemblyQualifiedName, typeConverter->AssemblyQualifiedName );}
PropertySpec(String* name, Type* type, String* category, String* description, Object* defaultValue,
Type* editor, Type* typeConverter)
{ Initialize( name, type->AssemblyQualifiedName, category, description, defaultValue, editor->AssemblyQualifiedName, typeConverter->AssemblyQualifiedName );}

void Initialize( String* name,
String* type,
String* category,
String* description,
Object* defaultValue,
String* editor,
String* typeConverter )
{
this->name = name;
this->type = type;
this->category = category;
this->description = description;
this->defaultValue = defaultValue;
this->attributes = NULL;
this->editor = editor;
this->typeConverter = typeConverter;
}
// [Properties]
public:
__property Attribute* get_Attributes() []
{
return attributes;
}
__property void set_Attributes( Attribute* pAtrtributes[] )
{
attributes = pAtrtributes;
}
__property String* get_Category()
{
return category;
}
__property void get_Category( String* strCategory )
{
category = strCategory;
}
__property String* get_ConverterTypeName()
{
return typeConverter;
}
__property void set_ConverterTypeName( String* strTypeConverter )
{
typeConverter = strTypeConverter;
}
__property Object* get_DefaultValue()
{
return defaultValue;
}
__property void set_DefaultValue( Object* pObject )
{
defaultValue = pObject;
}
__property String* get_Description()
{
return description;
}
__property void set_Description( String* strDescription )
{
description = strDescription;
}
__property String* get_EditorTypeName()
{
return editor;
}
__property void set_EditorTypeName( String* strEditor )
{
editor = strEditor;
}
__property String* get_Name()
{
return name;
}
__property void set_Name( String* strName )
{
name = strName;
}
__property String* get_TypeName()
{
return type;
}
__property void set_TypeName( String* strType )
{
type = strType;
}
// [Data Members]
private:
Attribute* attributes[];
String* category;
Object* defaultValue;
String* description;
String* editor;
String* name;
String* type;
String* typeConverter;
};

// Class: PropertySpecEventArgs
// Description: Provides data for the GetValue and SetValue events of the PropertyBag class.
public __gc class PropertySpecEventArgs : public EventArgs
{
// [Constructor]
public:
PropertySpecEventArgs( PropertySpec* property, Object* val )
{
this->property = property;
this->val = val;
}
// [Properties]
public:
__property PropertySpec* get_Property()
{
return property;
}
__property Object* get_Value()
{
return val;
}
__property void set_Value( Object* pVal )
{
val = pVal;
}
// Data Members]
private:
PropertySpec* property;
Object* val;
};
// Delegate: PropertySpecEventHandler
// Description: Represents the method that will handle the GetValue and SetValue events of the
// PropertyBag class.
public __delegate void PropertySpecEventHandler( Object* sender, PropertySpecEventArgs* e );
// Class: PropertyBag
// Description: Represents a collection of custom properties that can be selected into a
// PropertyGrid to provide functionality beyond that of the simple reflection
// normally used to query an object's properties.
public __gc class PropertyBag : public ICustomTypeDescriptor,
public CModifiableOwnerOwned
{
// [Inner Classes]
public:

// Class: PropertySpecCollection
// Description: Encapsulates a collection of PropertySpec objects.
[Serializable]
__gc class PropertySpecCollection : public IList
{
// [Constructors]
public:
PropertySpecCollection()
{
innerArray = new ArrayList();
}
// [Properties]
public:
__property Int32 get_Count()
{
return innerArray->Count;
}
__property Boolean get_IsFixedSize()
{
return false;
}

__property Boolean get_IsReadOnly()
{
return false;
}
__property Boolean get_IsSynchronized()
{
return false;
}
// ICollection
__property Object* get_SyncRoot()
{
return NULL;
}
/*
__property PropertySpec* get_Item( Int32 index )
{
return (PropertySpec*)innerArray->Item[index];
}
__property void set_Item( Int32 index, PropertySpec* pSpec )
{
innerArray->Item[index] = pSpec;
}
*/
// [General Interface]
public:
Int32 Add( PropertySpec* value )
{
Int32 index = innerArray->Add(value);
return index;
}
void AddRange( PropertySpec* array[] )
{
innerArray->AddRange( dynamic_cast<ICollection*>(array) );
}
void Clear()
{
innerArray->Clear();
}
Boolean Contains( PropertySpec* item )
{
return innerArray->Contains( item );
}
Boolean Contains( String* name )
{
const Int32 iCount = innerArray->Count;
for( Int32 iCur = 0; iCur < iCount; iCur++ )
{
PropertySpec* spec = dynamic_cast<PropertySpec*>( innerArray->Item[iCur] );
if( String::Equals(spec->Name, name ) )
{
return true;
}
}
return false;
}
void CopyTo( PropertySpec* array[] )
{
innerArray->CopyTo( array );
}
void CopyTo( PropertySpec* array[], Int32 index )
{
innerArray->CopyTo(array, index);
}
IEnumerator* GetEnumerator()
{
return innerArray->GetEnumerator();
}
Int32 IndexOf(PropertySpec* value)
{
return innerArray->IndexOf(value);
}
Int32 IndexOf( String* name)
{
for(int iCur = 0; iCur < innerArray->Count; iCur++ )
{
PropertySpec* spec = dynamic_cast<PropertySpec*>( innerArray->Item[iCur] );
if(String::Equals( spec->Name, name ) )
{
return iCur;
}
}
return -1;
}
void Insert(Int32 index, PropertySpec* value)
{
innerArray->Insert(index, value);
}
void Remove(PropertySpec* obj)
{
innerArray->Remove(obj);
}
void Remove(String* name)
{
Int32 index = IndexOf(name);
RemoveAt(index);
}
void RemoveAt(Int32 index)
{
innerArray->RemoveAt(index);
}
PropertySpec* ToArray() []
{
return dynamic_cast<PropertySpec*[]>(innerArray->ToArray(__typeof(PropertySpec)));
}
// ICollection
void CopyTo(Array* array, int index)
{
CopyTo(dynamic_cast<PropertySpec*[]>(array), index);
}
// IList
int Add(Object* value)
{
return Add((PropertySpec*)value);
}
// IList
bool Contains(Object* obj)
{
return Contains((PropertySpec*)obj);
}
// IList
Object* IList::get_Item(Int32 index)
{
return (PropertySpec*)innerArray->Item[index];
// return (PropertySpecCollection*)Item[index];
}
void IList::set_Item( Int32 index, Object* pObject )
{
innerArray->Item[index] = pObject;
// (PropertySpecCollection*)Item[index] = (PropertySpec*)pObject;
}
// IList
int IndexOf(Object* obj)
{
return IndexOf((PropertySpec*)obj);
}
// IList
void Insert(Int32 index, Object* value)
{
Insert(index, (PropertySpec*)value);
}
// IList
void Remove(Object* value)
{
Remove((PropertySpec*)value);
}
// [Data Members]
private:
ArrayList* innerArray;
};
// Class: PropertySpecDescriptor
__gc class PropertySpecDescriptor : public PropertyDescriptor
{
// [Constructors]
public:
PropertySpecDescriptor(PropertySpec* item,
PropertyBag* bag,
String* name,
Attribute* attrs[]) :
PropertyDescriptor(name, attrs)
{
this->bag = bag;
this->item = item;
}
// [Properties]
public:
__property virtual Type* get_ComponentType()
{
return item->GetType();
}
__property virtual Boolean get_IsReadOnly()
{
return Attributes->Matches(ReadOnlyAttribute::Yes);
}
__property virtual Type* get_PropertyType()
{
return Type::GetType(item->TypeName);
}
// [PropertyDescriptor Overridables]
public:
virtual Boolean CanResetValue( Object* component )
{
if(item->DefaultValue == NULL)
{
return false;
}
else
{
return !this->GetValue(component)->Equals(item->DefaultValue);
}
}
virtual Object* GetValue(Object* component)
{
// Have the property bag raise an event to get the current value
// of the property.
PropertySpecEventArgs* e = new PropertySpecEventArgs(item, NULL);
bag->OnGetValue(e);
return e->Value;
}
virtual void ResetValue(Object* component)
{
SetValue(component, item->DefaultValue);
}
virtual void SetValue(Object* component, Object* value)
{
// Have the property bag raise an event to set the current value
// of the property.
PropertySpecEventArgs* e = new PropertySpecEventArgs(item, value);
bag->OnSetValue(e);
}
virtual bool ShouldSerializeValue(Object* component)
{
Object* val = this->GetValue(component);
if(item->DefaultValue == NULL && val == NULL)
{
return false;
}
else
{
return !val->Equals(item->DefaultValue);
}
}
// [Data Members]
private:
PropertyBag* bag;
PropertySpec* item;
};

// [Constructor]
public:
explicit PropertyBag( String* const strOwnedType ) : CModifiableOwnerOwned(strOwnedType)
{
defaultProperty = NULL;
properties = new PropertySpecCollection();
}
// [Properties]
public:
String* get_DefaultProperty()
{
return defaultProperty;
}
void set_DefaultProperty( String* strDefaultProperty )
{
defaultProperty = strDefaultProperty;
}
PropertySpecCollection* get_Properties()
{
return properties;
}
// [Events]
public:
__event PropertySpecEventHandler* GetValue;
__event PropertySpecEventHandler* SetValue;
// [ICustomTypeDescriptor Overridables]
public:

// Most of the functions required by the ICustomTypeDescriptor are
// merely pssed on to the default TypeDescriptor for this type,
// which will do something appropriate. The exceptions are noted
// below.
AttributeCollection* GetAttributes()
{
return TypeDescriptor::GetAttributes(this, true);
}
String* GetClassName()
{
return TypeDescriptor::GetClassName(this, true);
}
String* GetComponentName()
{
return TypeDescriptor::GetComponentName(this, true);
}
TypeConverter* GetConverter()
{
return TypeDescriptor::GetConverter(this, true);
}
EventDescriptor* GetDefaultEvent()
{
return TypeDescriptor::GetDefaultEvent(this, true);
}
PropertyDescriptor* GetDefaultProperty()
{
// This function searches the property list for the property
// with the same name as the DefaultProperty specified, and
// returns a property descriptor for it. If no property is
// found that matches DefaultProperty, a NULL reference is
// returned instead.
PropertySpec* propertySpec = NULL;
if(defaultProperty != NULL)
{
Int32 index = properties->IndexOf(defaultProperty);
propertySpec = dynamic_cast<PropertySpec*>( properties->Item[index] );
}
if(propertySpec != NULL)
{
return new PropertySpecDescriptor(propertySpec, this, propertySpec->Name, NULL);
}
else
{
return NULL;
}
}
Object* GetEditor(Type* editorBaseType)
{
return TypeDescriptor::GetEditor(this, editorBaseType, true);
}
EventDescriptorCollection* GetEvents()
{
return TypeDescriptor::GetEvents(this, true);
}
EventDescriptorCollection* GetEvents(Attribute* attributes[])
{
return TypeDescriptor::GetEvents(this, attributes, true);
}
PropertyDescriptorCollection* GetProperties()
{
return GetProperties( new Attribute*[0] );
}
PropertyDescriptorCollection* GetProperties(Attribute* attributes[])
{
// Rather than passing this function on to the default TypeDescriptor,
// which would return the actual properties of PropertyBag, I construct
// a list here that contains property descriptors for the elements of the
// Properties list in the bag.
ArrayList* props = new ArrayList();
for(Int32 iCurProperty = 0; iCurProperty < properties->Count; iCurProperty++ )
{
PropertySpec* property = dynamic_cast<PropertySpec*>( properties->Item[iCurProperty] );
ArrayList* attrs = new ArrayList();
// If a category, description, editor, or type converter are specified
// in the PropertySpec, create attributes to define that relationship.
if(property->Category != NULL)
{
attrs->Add(new CategoryAttribute(property->Category));
}
if(property->Description != NULL)
{
attrs->Add(new DescriptionAttribute(property->Description));
}
if(property->EditorTypeName != NULL)
{
attrs->Add(new EditorAttribute(property->EditorTypeName, __typeof(UITypeEditor)));
}
if(property->ConverterTypeName != NULL)
{
attrs->Add(new TypeConverterAttribute(property->ConverterTypeName));
}
// Additionally, append the custom attributes associated with the
// PropertySpec, if any.
if(property->Attributes != NULL)
{
attrs->AddRange( dynamic_cast<ICollection*>(property->Attributes) );
}
Attribute* attrArray[] = dynamic_cast<Attribute*[]>(attrs->ToArray(__typeof(Attribute)));
// Create a new property descriptor for the property item, and add
// it to the list.
PropertySpecDescriptor* pd = new PropertySpecDescriptor(property,
this, property->Name, attrArray);
props->Add(pd);
}
// Convert the list of PropertyDescriptors to a collection that the
// ICustomTypeDescriptor can use, and return it.
PropertyDescriptor* propArray[] = dynamic_cast<PropertyDescriptor*[]>(props->ToArray(__typeof(PropertyDescriptor)));
return new PropertyDescriptorCollection(propArray);
}
Object* GetPropertyOwner(PropertyDescriptor* pd)
{
return this;
}
// [Helper methods]
protected:

virtual void OnGetValue(PropertySpecEventArgs* e)
{
if(GetValue != NULL)
{
GetValue(this, e);
}
}
virtual void OnSetValue(PropertySpecEventArgs* e)
{
if(SetValue != NULL)
{
SetValue(this, e);
}
}
// [Data Members]
private:
String* defaultProperty;
PropertySpecCollection* properties;
};
// Class: PropertyTable
/// An extension of PropertyBag that manages a table of property values, in
/// addition to firing events when property values are requested or set.
/// </summary>
public __gc class PropertyTable : public PropertyBag
{
// [Constructor]
public:
PropertyTable( String* const strOwnedType ) : PropertyBag(strOwnedType)
{
propValues = new Hashtable();
}
// [Properties]
public:
__property Object* get_Item(String* key)
{
return propValues->Item[key];
}
__property void set_Item(String* key, Object* pObject )
{
propValues->Item[key] = pObject;
}
// [PropertyBag Overridables]
protected:
virtual void OnGetValue(PropertySpecEventArgs* e)
{
e->Value = propValues->Item[e->Property->Name];
__super::OnGetValue(e);
}
virtual void OnSetValue(PropertySpecEventArgs* e)
{
propValues->Item[e->Property->Name] = e->Value;
__super::OnSetValue(e);
}
// [Data Members]
private:
Hashtable* propValues;
};
}
}

[21165 byte] By [Samyag1] at [2007-12-21]
# 1
Ok, I figured out what the problem was, and wanted to post it incase anyone else runs into it. Also, I'd like to understand why my fix works. The problem was that I was labeling two of the methods of an inner class with an explicit interface member initialization. Here's the code:
// IList
Object* IList::get_Item(Int32 index)
{
return static_cast<PropertySpec*>( innerArray->Item[index] );
}
void IList::set_Item( Int32 index, Object* pObject )
{
innerArray->Item[index] = pObject;
}
It is the IList:: that prepends the method names that was the problem. What I think this does it makes these methods private when using the class normally, but if the class was cast to an IList then these methods would become public. What I don't understand is why this caused the error that it did. It seems to me that this sort of problem could have been caught by the compiler instead of a cryptic runtime error for which there is no documentation. Anyways, if anyone has any insight into why this was a problem, I'd like to know. Thanks -
Samy
Samyag1 at 2007-9-10 > top of Msdn Tech,Visual C++,Visual C++ General...
# 2

//In Visual Studio 2005 , try :

virtual property Object^ default[int]
{
Object^ get(int index)
{
return dynamic_cast<PropertySpec^>(innerArray[index]);
}
void set(int index, Object^ value)
{
innerArray[index] =dynamic_cast<PropertySpec^>(value);
}
}

JamskinChen at 2007-9-10 > top of Msdn Tech,Visual C++,Visual C++ General...