Search code examples
sqlitexamarin.iosxamarinportable-class-libraryexecutequery

Xamarin PCL and sqlite.net


I would have the need, in a pcl Xamarin, to pass to a function a type, which is then used to perform a query. The code that I tried to use is this:

public object sqlLeggi(string sql, Type myType){
 SQLiteCommand cmd = DB.CreateCommand(sql);
 var results = cmd.ExecuteQuery< myType > ();
[..]
}

but it does not work, give me this error:

The type or namespace 'myType' could not be found.

Does anyone know if it is possible to do such a thing?

Thank you very much


Solution

  • The myType in the two statements play very different roles:

    public object sqlLeggi(string sql, Type myType){
    

    Here, myType is a Type object, referencing an instance of the Type class.

    var results = cmd.ExecuteQuery< myType > ();
    

    Here, myType is a Type identifier, which is a syntactic construct referring to a specific type, one that would actually be named myType in this case.

    Now, there is usually two ways to handle this specific problem:

    1. Look at the object type in cmd and see if there is an overload or alternative method to ExecuteQuery that takes a Type object parameter instead
    2. Make your method generic so that you don't have a Type object to begin with.

    The first case would presumably be written in this way:

    var results = cmd.ExecuteQuery(myType);
    

    The second like this:

    public myType sqlLeggi<myType>(string sql{
        SQLiteCommand cmd = DB.CreateCommand(sql);
        var results = cmd.ExecuteQuery< myType > ();
        [..]
    }
    

    Note that:

    1. I made the method return myType instead of object
    2. myType is now specified as a generic parameter to the method: sqlLeggi<myType>

    Naming convention in this case would dictate that your generic type parameter be named T or something beginning with T so here is my advice:

    public T sqlLeggi<T>(string sql{
        SQLiteCommand cmd = DB.CreateCommand(sql);
        var results = cmd.ExecuteQuery<T>();
        [..]
    }