CONVERSAO DE PARAMETROS DO TIPO GENERICO VB.NET/C#

TUNUSAT 13/03/2014 09:58:19
#435984
Por favor pessoALL,

Traduzi de VB.Net para C#.Net a seguintes linhas:
Dim objeto As T
objeto = Activator.CreateInstance(GetType(T), dataReader)

Usando o tradutor do Macoratti (http://www.macoratti.net/11/11/ConversorCodigo2011.zip) para C#:
T objeto;
objeto = Activator.CreateInstance(typeof(T), dataReader);

Mas está apresentando o seguinte erro:
[Ô]Error: Cannot implicitly convert type [ô]object[ô] to [ô]T[ô]. An explicit conversion exists (are you missing a cast?)[Ô]
Tradução Google Tradutor:
[Ô]Erro: Não é possível converter implicitamente o tipo [ô]objeto[ô] de [ô]T[ô]. Existe uma conversão explícita (faltam um elenco?)[Ô] ...
(are you missing a cast?) -> (Você perdeu o conversor?)
O código das funções completo são:
Protected Function RetornaLista(ByVal commandText As String, Optional ByVal isSql As Boolean = True) As List(Of T)

Dim listaRetorno As List(Of T) = Nothing

If isSql Then
Using dataReader As SqlClient.SqlDataReader = SQLHelper.ExecuteReader(commandText)
If dataReader.HasRows Then
listaRetorno = New List(Of T)()
While dataReader.Read()
Dim objeto As T
objeto = Activator.CreateInstance(GetType(T), dataReader)
listaRetorno.Add(objeto)
End While
End If
End Using
End If
Return listaRetorno

End Function


A tradução da função completa fica assim:

protected List<T> RetornaLista(string commandText, [System.Runtime.InteropServices.OptionalAttribute, System.Runtime.InteropServices.DefaultParameterValueAttribute(true)] bool isSql)
{
List<T> listaRetorno = null;
if (isSql)
{
using (System.Data.SqlClient.SqlDataReader dataReader = SQLHelper.ExecuteReader(commandText))
{
if (dataReader.HasRows)
{
listaRetorno = new List<T>();
while (dataReader.Read())
{
T objeto;
objeto = Activator.CreateInstance(typeof(T), dataReader);
listaRetorno.Add(objeto);
}
}
}
}
return listaRetorno;
}

Tentei reescrever de várias formas:
objeto = Convert.ChangeType(Activator.CreateInstance(typeof(T), dataReader), T);

Apareceu o erro:
[ô]T[ô] is a [ô]type parameter[ô] but is used like a [ô]variable[ô]
Tradução Google:
[ô]T[ô] é um [ô]tipo de parâmetro [Ô], mas é usado como uma[Ô] variável [Ô]
objeto = Convert.ChangeType(Activator.CreateInstance(typeof(T), dataReader), <T>);

objeto = Convert.ChangeType(Activator.CreateInstance(typeof(T), dataReader), objeto.GetType);


Olhei também os sites, mas não entendi:

Generic Type Parameters (C# Programming Guide)
http://msdn.microsoft.com/en-us/library/0zk36dx2.aspx

Generics in the Run Time (C# Programming Guide)
http://msdn.microsoft.com/en-us/library/f4a6ta2h.aspx

Veja este trecho:

Citação:

However, suppose that another Stack<T> class with a different value type such as a long or a user-defined structure as its parameter is created at another point in your code. As a result, the runtime generates another version of the generic type and substitutes a long in the appropriate locations in MSIL. Conversions are no longer necessary because each specialized generic class natively contains the value type.


Citação:

No entanto , suponha que uma outra classe Stack <T> com um tipo de valor diferente, como uma longa ou uma estrutura definida pelo usuário como seu parâmetro é criado em outro ponto no seu código. Como resultado, o tempo de execução gera outra versão do tipo genérico e substitui um longo nos locais apropriados na MSIL . Conversões não são mais necessárias porque cada classe genérica especializado nativamente contém o tipo de valor.



Outra fonte:

Genéricos (Guia de Programação em C#)
http://msdn.microsoft.com/pt-br/library/512aeb7t.aspx

Em outro tópico que eu postei o [Ô]OCELOT[Ô] me disse que os conversores não entendem bem [Ô]generics[Ô] ... é verdade!

Eu não estou entendendo como fazer!!! Não precisa de conversão então? Como faz isto no C#?
Por favor, alguém pode me ajudar?

Obrigado,
Tunusat.
ASHKATCHUP 13/03/2014 10:41:07
#435990
Resposta escolhida
Tenta assim:


objeto = (T)Activator.CreateInstance(typeof(T), dataReader);
TUNUSAT 13/03/2014 11:09:11
#435992
ASHKATCHUP,

Não apresentou erro. Acho que este é o casting correto!
Por favor, como faço isto sem list? Função abaixo:

protected T RetornaUnico(string commandText, [System.Runtime.InteropServices.OptionalAttribute, System.Runtime.InteropServices.DefaultParameterValueAttribute(true)] bool isSql)
{
if (isSql)
{
using (System.Data.SqlClient.SqlDataReader dataReader = SQLHelper.ExecuteReader(commandText))
{
if (dataReader.HasRows)
{
while (dataReader.Read())
{
T objeto;
objeto = Activator.CreateInstance(typeof(T), dataReader);
return objeto;
}
}
}
}
}



Obrigado,
Tunusat.
ASHKATCHUP 13/03/2014 11:59:47
#435998
Da mesma maneira que na lista, mestre.

Como [Ô]T[Ô] não é um tipo definido naquela função, e sim passado posteriormente, tu pode utilizar ele para fazer o cast quando quiser.
TUNUSAT 13/03/2014 13:32:34
#436006
ASHKATCHUP,

é isto mesmo. Fiz as alterações abaixo e não deu erro. Vou testar tudo agora. Obrigado.
protected T RetornaUnico(string commandText, [System.Runtime.InteropServices.OptionalAttribute, System.Runtime.InteropServices.DefaultParameterValueAttribute(true)] bool isSql)
{
T Retorno = default(T);
if (isSql)
{
using (System.Data.SqlClient.SqlDataReader dataReader = SQLHelper.ExecuteReader(commandText))
{
if (dataReader.HasRows)
{
while (dataReader.Read())
{
T objeto;
objeto = (T)Activator.CreateInstance(typeof(T), dataReader);
Retorno = (T)objeto;
}
}
}
}
return Retorno;
}


Obrigado!
[][ô]s,
Tunusat
Tópico encerrado , respostas não são mais permitidas