CONVERSAO DE PARAMETROS DO TIPO GENERICO VB.NET/C#
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.
objeto = (T)Activator.CreateInstance(typeof(T), dataReader);
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.
Como [Ô]T[Ô] não é um tipo definido naquela função, e sim passado posteriormente, tu pode utilizar ele para fazer o cast quando quiser.
é 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