12
votes

Définir la propriété nullable <> par réflexion

J'essaie de définir une propriété nullable Dynamicly.

Je reçois mon property ex: p> xxx pré>

Je veux mettre ma propriété par réflexion comme p >

Nullable.GetUnderlyingType(property.PropertyType)
  • J'essaie de créer une instance de ma nullable propriété avec p>

    var nullvar = activator.createinstance (typeof (Nullable ). Makenerictype (nouveau type [] {nullable.gettyLyingType (propriété.propertype)})); p> li> ul>

    mais nullvar est toujours null p> p>


3 commentaires

Est-ce que cela fonctionne lorsque vous définissez un entier au lieu d'une chaîne? "1256" est une chaîne, pas un entier.


Cela fonctionnera, mais le but est que je ne connais pas le type de propriété nullable. Je pourrais utiliser Nullable.getUnderlyingType (propriété.propertytype) pour obtenir le type


NULLLABLE <> Impossible d'utiliser String pour le type sous-jacent sous la forme String est un type de référence. En d'autres termes, typeof (nullable <>). Makenerictype (t); ira bien si t == typeof (int) , mais il va exploser (contrainte non remplie) avec t == typeof (chaîne) . Donc, nullable <> ne sera en aucune manière comme une sorte de type "type commun" pour les types de référence et les types de valeur nullables.


6 Réponses :


9
votes

Si c'est une nullable INT, vous devrez utiliser un paramètre INT, pas une chaîne.

 var nullType = Nullable.GetUnderlyingType(property.PropertyType)
 var value = Convert.ChangeType("1256", nullType );
 property.SetValue(klass, value, null );


2 commentaires

Je sais que c'est une corde mais c'est générique donc je ne sais donc pas quel sera le type. Ce n'est qu'un exemple, mon français nullable <> pourrait être une chaîne, int une conversion générique sera effectuée


Vous ne pouvez pas avoir de nullable , puisque chaîne n'est pas une valeur de valeur.



2
votes

"1256" est une chaîne, pas un int.


0 commentaires

5
votes

Voici un exemple complet montrant comment faire:

using System;
using System.Reflection;

class Test
{
    static void Main()
    {
        Foo foo = new Foo();

        PropertyInfo property = typeof(Foo).GetProperty("Bar");
        Object value =
            Convert.ChangeType("1234",
                Nullable.GetUnderlyingType(property.PropertyType)
                ?? property.PropertyType);

        property.SetValue(foo, value, null);
    }
}

class Foo
{
    public Nullable<Int32> Bar { get; set; }
}


0 commentaires

17
votes

Si vous souhaitez convertir une chaîne arbitraire au type sous-juliable de la nullable, vous pouvez utiliser la classe de convertis: xxx

Cet exemple fonctionnera si le type cible est INT, court, Longues (ou des variantes non signées, puisque la chaîne d'entrée représente un nombre non négatif), double, flotteur ou décimale. CAVEAT: Ce n'est pas un code rapide.


0 commentaires

3
votes

Je frappe ce même problème ainsi qu'un problème avec convertir.Changetype ne manipulant pas les quolles sur des nullables, donc j'ai combiné quelques solutions Stackoverflow avec une magie dynamique .NET 4 pour obtenir quelque chose de doux. Si vous regardez le code, nous utilisons dynamique pour taper l'objet nullable au moment de l'exécution, puis le temps d'exécution le traite différemment et permet aux attributions du type de base à l'objet nullable.

public void GenericMapField(object targetObj, string fieldName, object fieldValue)
{
    PropertyInfo prop = targetObj.GetType().GetProperty(fieldName);
    if (prop != null)
    {
        if (prop.PropertyType.IsGenericType && prop.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
        {
            dynamic objValue = System.Activator.CreateInstance(prop.PropertyType);
            objValue = fieldValue;
            prop.SetValue(targetObj, (object)objValue, null);
        }
        else
        {
            prop.SetValue(targetObj, fieldValue, null);
        }
    }
}


1 commentaires

C'était utile. Merci



1
votes
public static void SetValue(object target, string propertyName, object value)
{
  if (target == null)
    return;

  PropertyInfo propertyInfo = target.GetType().GetProperty(propertyName);

  object convertedValue = value;
  if (value != null && value.GetType() != propertyInfo.PropertyType)
  {
    Type propertyType = Nullable.GetUnderlyingType(propertyInfo.PropertyType) ?? propertyInfo.PropertyType;
    convertedValue = Convert.ChangeType(value, propertyType);
  }

  propertyInfo.SetValue(target, convertedValue, null);
}

1 commentaires

Nullable.getUnderlyType () était la clé de ma solution. Grande contribution!