问题
I am new to Vala and playing around a bit. Currently I am looking for a way to determine the type parameter of a generic list at runtime.
The code below uses 'reflection' to print the properties of the Locations class. However, I am not able to determine at runtime that this list contains instances of string.
Is there a way to do this? Or is this not supported in Vala?
using Gee;
class Locations : Object {
public string numFound { get; set; }
public ArrayList<string> docs { get; set; }
}
void main () {
ObjectClass ocl = (ObjectClass) typeof (Locations).class_ref ();
ParamSpec[] properties = ocl.list_properties ();
foreach (ParamSpec spec in properties) {
string fieldName = spec.get_nick ();
stdout.printf (" fieldName: %s\n", fieldName);
Type fieldType = spec.value_type;
stdout.printf (" Type : %s\n", fieldType.name());
}
}
Output:
fieldName: numFound
Type : gchararray
fieldName: docs
Type : GeeArrayList
回答1:
There isn't a generic way to do this since GObject/GType simply isn't that expressive. For example, if you were using a GLib.GenericArray
(or a GLib.List
) instead of a Gee.ArrayList
you would be out of luck.
That said, libgee does provide a way. Like most containers in libgee, Gee.ArrayList
implements Gee.Traversable, which includes the element_type property. Note, however, that you need an instance, not just the GLib.ObjectClass
.
回答2:
With the help of the suggestion of the first answer, I have come up with this solution. This is exactly what I was looking for:
using Gee;
class Locations : Object {
public int numFound { get; set; }
public Gee.List<string> docs { get; set; }
public Locations () {
docs = new ArrayList<string>();
}
}
void main () {
ObjectClass ocl = (ObjectClass) typeof (Locations).class_ref ();
ParamSpec[] properties = ocl.list_properties ();
Locations locs = new Locations();
foreach (ParamSpec spec in properties) {
string fieldName = spec.get_nick ();
Type fieldType = spec.value_type;
// get the docs instance from the locations instance
GLib.Value props = Value( fieldType);
locs.get_property(fieldName, ref props);
stdout.printf ("Field type %s : %s\n", fieldName, props.type_name());
if(props.holds(typeof (Gee.Iterable))) {
Gee.Iterable docs = (Gee.Iterable)props.get_object();
stdout.printf ("\tList parameter type : %s\n", docs.element_type.name());
}
}
}
Output:
Field type numFound : gint
Field type docs : GeeList
List parameter type : gchararray
来源:https://stackoverflow.com/questions/24710328/vala-determine-generic-type-inside-list-at-runtime