2015-06-10 1 views
0

Что я хочу сделать, это прочитать все, что находится в моей базе данных lex.db. Предпочтительно выгружать страницы с заранее заданным размером. Я сделал следующее:Получить тип программно и использовать его как typeparam

DbInstance database = GetDatabase(); 
var tables = database.AllTables(); 
foreach (var table in tables) 
{ 
    string str = table.ToString(); 
    str = str.Replace("Lex.Db.DbTable`1[", string.Empty); 
    str = str.Replace("]", string.Empty); 
    Type t = Type.GetType(str); 

    if (t != null) 
    { 
    var columns = database.ReadAll<t>(); 
    //handle all columns 
    } 
} 

Проблема в том, что функция ReadAll имеет typeparam. Я предположил, что могу использовать этот тип как typeparam, так как он представляет класс, который я хочу получить.

Однако я получаю ошибку:

"The type or namespace name 't' could not be found (are you missing a using directive or an assembly reference?)".

Так как я могу сделать это так, что фактический тип будет использоваться в качестве typeparam вместо буквы «т»?

Я создаю окна универсальное приложение для окон 8.1 и Windows Phone 8,1

EDIT:

Исходя из предположения, что romkyns и Стефан Steinegger дал я попытался с помощью отражения. У меня теперь есть следующий код:

DbInstance database = DbInstance.GetInstance(); 

System.Type thisType = database.GetType(); 
TypeInfo thisTypeInfo = thisType.GetTypeInfo(); 
MethodInfo method = thisTypeInfo.GetDeclaredMethod("LoadAll"); 

var tables = database.AllTables(); 
foreach (var table in tables) 
{ 
    string str = table.ToString(); 
    str = str.Replace("Lex.Db.DbTable`1[", string.Empty); 
    str = str.Replace("]", string.Empty); 
    Type t = Type.GetType(str); 
    if (t != null) 
    { 
     MethodInfo generic = method.MakeGenericMethod(t); 
     object[] parameters = { this, null }; 
     var columns = generic.Invoke(database, parameters); 

     if (columns != null) 
     { 
      //handle columns 
     } 
    } 
} 

Это работает до такой степени, что вызывается метод вызова. В этот момент возникает следующее исключение:

An exception of type 'System.Reflection.TargetException' occurred in mscorlib.dll but was not handled in user code

Additional information: Object does not match target type.

Любые подсказки о том, как разрешить это?

EDIT II:

метод

ВЫЗОВ должен был называться:

var columns = generic.Invoke(database, null); 
+0

Я не думаю, что это возможно, дженерики должны быть известны во время компиляции. Может быть, через какую-то форму отражения? – Barnstokkr

ответ

1

Единственный способ сделать вызов, как это в use reflection. Предполагается, что <T> будет известен во время компиляции, но в вашем случае это не так, поэтому вы не можете сделать это так.

Такие API часто имеют перегрузку, которая занимает Type. Проверьте, есть ли у вас. Это может выглядеть примерно так:

database.ReadAll(t); 
+0

Нет такой функции, которая слишком плоха, потому что это было бы намного проще. – WereWolfBoy

+0

Я отредактировал исходное сообщение. После попытки отражения я столкнулся с другой проблемой. У вас есть какие-то предложения? – WereWolfBoy

+0

@WereWolfBoy Проблема теперь, вероятно, в том, что вы передаете «это» вместо «базы данных». Вам нужно передать объект, по которому вы вызываете метод. Прочитайте документацию по Invoke; он должен объяснить, что происходит. –

1

Вы должны использовать отражение. Это не представляется возможным комбинировать типы во время выполнения с компиляции типов времени по-другому:

(может быть неправильным, просто сердце, это выглядит примерно так :)

var dbInstanceType = typeof(DbInstance); 
var readAllMethod = dbInstanceType.GetMethod("ReadAll"); 
var typedReadAllMethod = readAllMethod.BuildGenericMethod(t); 
var result = typedReadAllMethod.Invoke(dbInstanceType); 

Обычно у вас есть, не универсальный метод для передачи во время выполнения типов, поскольку в этом случае дженерики не имеют смысла.

+0

Спасибо за ваш ответ. Я отредактировал оригинальный пост. После попытки отражения я столкнулся с другой проблемой. У вас есть какие-то предложения? – WereWolfBoy

Смежные вопросы