Vala: determine generic type inside List at runtime

吃可爱长大的小学妹 提交于 2019-12-11 11:56:23

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!