Pergunta

Eu estou tentando escrever algum código para converter dados de um campo de tipo de objeto (vêm de um DataSet) em seu destino (digitado) Campos. Eu estou fazendo (tentar pelo menos)-lo usando conversão dinâmica. Parece funcionar bem para cordas, int, DateTime.

Mas ele não funciona para os tipos não assinados (ULONG, uint). Abaixo há um código simples que mostra o que eu quero fazer. Se você alterar o tipo de var ul de ulong para int, ele funciona bem.

Alguém tem uma pista?

public class console
{

    public static void CastIt<T>(object value, out T target)
    {
        target = (T) value;
    }

    public static void Main()
    {
        ulong ul;
        string str;
        int i;
        DateTime dt;

        object ul_o = (object) 2;
        object str_o = (object) "This is a string";
        object i_o = (object)1;
        object dt_o = (object) DateTime.Now;

        Console.WriteLine("Cast");

        CastIt(ul_o, out ul);
        CastIt(str_o, out str);
        CastIt(i_o, out i);
        CastIt(dt_o, out dt);

        Console.WriteLine(ul);
        Console.WriteLine(str);
        Console.WriteLine(i);
        Console.WriteLine(dt.ToString());
    }

}
Foi útil?

Solução

Como Andrew diz, o problema é que você não pode unbox de um int boxed para ulong.

Duas opções:

1) Caixa um ulong vez:

object ul_o = (object) 2UL;

ou

ulong tmp = 2;
object ul_o = tmp;

2) Faça uso CastIt<T> Convert.ChangeType:

public static void CastIt<T>(object value, out T target)
{
    target = (T) Convert.ChangeType(value, typeof(T));
}

Este é um pouco malcheiroso, mas funciona com o seu código de exemplo. Se você pode usar a primeira maneira em seu código real, que seria melhor.

Outras dicas

Isso porque o seu objeto ul_o é um int, e não um número sem sinal. Quando você está em sua função de casting, você está lançando ao ter os dados de destino no contexto de um object. operadores explícitos / implícitos elenco (que é o que você precisa estar usando) só funcionam quando você tem o objeto no contexto de um tipo que implementa (desde os operadores são estaticamente ligado em tempo de compilação em vez de dinamicamente em tempo de execução).

Se este é realmente o que você quer fazer, em vez de apenas um elenco reta, use o seguinte:

target = (T)Convert.ChangeType(value, typeof(T));

O CLR não permite que você para converter este caminho, porque o seu tipo de valor em caixa é de fato um int:

object ul_o = (object)2;

Quando você está tentando fundido a um ulong você não pode porque você não pode unbox um int diretamente em um ulong.

Eu acho que o que você quer é mais como (não testado, mas direcionalmente correto) ...

public static void CastIt<T>( object value ) where T : IConvertable
{
  return ( T )Convert.ChangeType( value , typeof( T ) );
}

Edit: escavado por Skeet! :)

Isto não é realmente uma resposta à sua pergunta; Só queria mencionar que, se você estiver usando o .Net 3.5, a Linq para código DataSets inclui funcionalidades como o que você está implementando. O método de extensão específico seria Campo () na classe DataRow.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top