Generic Type Limitations in .NET

.NET 2.0 introduced the concept of templated type via Generics. Generics basically allow runtime type substitution for for .NET types causing the compiler to dynamically generate new types during JIT compilation of .NET code. Generics are most frequently used in combination with List types (ie. List) where the type passed becomes the strongly typed item value used for the items in the collection/list.

Because Generic types are dynamic they are not directly accessible via COM Interop - they can't be directly instantiated through COM although you can with wwDotNetBridge (because it essentially uses .NET internally to instantiate the type) and members on them can't be accessed directly through COM interop.

You can still access Generic types with wwDotnetBridge however, by using the Reflection method of the class. You can use InvokeMethod, Get/SetProperty to access values and call methods on generic types as these operation are essentially proxied into .NET code which in turn performs the operations and returns the raw result back to FoxPro. Essentially the types travel but the COM interfaces on them are non-functional so Reflection is required to make the calls.

For example, assume the following definition of a collection of Person object:

public List<Person> Persons
{
    get { return _Persons; }
    set { _Persons = value; }
}
private List<Person> _Persons = new List<Person>();

To add and remove items from this generic list you can use code like the following:

DO wwDotNetBridge
loBridge = CREATEOBJECT("wwDotNetBridge")

*** Create the main type that holds Persons list
loItem = loBridge.CreateInstance("Westwind.WebConnection.VfpTestClass")

*** Create new Person object and set properties
loPerson = loBridge.CreateInstance("Westwind.WebConnection.Person")
loPerson.Name = "Jumbo"

** This won't work directly - not enough storage COM error
*loItem.Persons.Add(loPerson)  

*** Call Add() using Reflection
loBridge.InvokeMethod(loItem.Persons,"Add",loPerson)

*** Again this won't work
*loItem = loItem.Persons[0]

*** Retrieve indexed property with Reflection
loPerson = loBridge.GetPropertyEx(loItem,"Persons[0]")
? loPerson.Name

*** Assign an index property value
loBridge.SetPropertyEx(loItem,"Persons[0]",loPerson)

© West Wind Technologies, 2023 • Updated: 04/27/17
Comment or report problem with topic