it-swarm-pt.tech

Reflexão em C #: Como obter o tipo de um <int> nulo?

O que eu quero fazer é algo como isto:

switch( myObject.GetType().GetProperty( "id") )
{
    case ??: 
        // when Nullable<Int32>, do this
    case ??:
        // when string, do this
    case ??:
        // when Nullable<bool>, do this

Que caminho em object.GetType () teria o nome da string do tipo de dados que eu poderia comparar usando uma instrução de caso? Eu preciso saber o tipo para que eu possa ter um dos muitos Convert.ToInt32 (string) que definirá o valor de myObject usando Reflection.

31
Zachary Scott

Atualização: parece que o C # 7 suportará a ativação de Types como o solicitante desta pergunta estava tentando fazer. É um pouco diferente, portanto, cuidado com as minas terrestres de sintaxe.

Você não precisa de um nome de string para compará-lo:

if (myObject.GetType().GetProperty("id").PropertyType == typeof(Nullable<Int32>))
    // when Nullable<Int32>, do this
else if (myObject.GetType().GetProperty("id").PropertyType == typeof(string))
    // when string, do this
else if (myObject.GetType().GetProperty("id").PropertyType == typeof(Nullable<bool>))
    // when Nullable<bool>, do this
13
M.Babcock

Eu tenho usado o seguinte tipo de código para verificar se o tipo é anulável e para obter o tipo real:

if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
{
    return Nullable.GetUnderlyingType(type);
}

Se o tipo for p. Anulável esse código retorna a parte int (tipo subjacente). Se você apenas precisar converter um objeto em um tipo específico, poderá usar System.Convert.ChangeType método.

63
Toni Parviainen

A questão é muito confusa. "MyObject" é o objeto que pode ser um int nulo? Ou a propriedade "id" é possivelmente do tipo int nulo?

No primeiro caso, sua pergunta não pode ser respondida porque pressupõe uma falsidade. Não existe um int anulável em caixa. Observo que todas as respostas que propõem if (myobject.GetType() == typeof(int?)) estão, portanto, incorretas; a condição nunca será verdadeira.

Quando você converte um int anulável em objeto, ele se torna uma referência nula (se o int anulável não tiver nenhum valor) ou se torna um int em caixa. Não há como determinar se um objeto contém um int nulo porque um objeto nunca contém um int nulo.

Nesse último caso, compare tipo de propriedade a typeof(int?). Você não pode usar um switch; somente constantes podem ser usadas para casos de comutação e os tipos não são constantes.

Tudo o que disse, este é um mau cheiro de código. Por que você está usando a reflexão em primeiro lugar?

18
Eric Lippert

No .net, instâncias de tipos de valor são apenas coleções de bits, sem informações de tipo associadas. Para cada tipo de valor diferente de Nullable<T>, no entanto, o sistema também gera automaticamente um tipo de classe correspondente que deriva de System.ValueType. Existe uma conversão ampliada do tipo de valor para o tipo de classe gerado automaticamente e uma conversão restrita do tipo de classe gerado automaticamente para o tipo de valor. No caso de Nullable<T>, não há tipo de classe gerado automaticamente correspondente com conversões de/para o tipo de valor; em vez disso, existem conversões ampliadas nas duas direções entre Nullable<T> e o tipo de classe associado a T.

Até onde eu sei, esse comportamento estranho foi implementado para permitir comparações entre null e um vazio Nullable<T> para retornar verdadeiro.

2
supercat

Como disse @Cody Gray, se as declarações provavelmente seriam a melhor maneira

var t = myObject.GetType();

if (t == typeof(Nullable<int>))
{ }
else if (t == typeof(string))
{}
else if (t==typeof(Nullable<bool>))
{}
0
heads5150