Question

J'ai une classe que je veux utiliser pour stocker des "propriétés" pour une autre classe.Ces propriétés n'ont tout simplement un nom et une valeur.Idéalement, ce que je voudrais, c'est être en mesure d'ajouter tapé propriétés, de façon que la valeur retournée est toujours du type que je veux qu'il soit.

Le type doit toujours être primitive.Cette classe de sous-classes d'une classe abstraite qui, fondamentalement, stocke le nom et la valeur de chaîne.L'idée étant que la présente sous-classe d'ajouter un peu de sécurité du type de la classe de base (ainsi que la sauvegarde de moi sur certains de conversion).

Donc, j'ai créé une classe qui est (à peu près) ce:

public class TypedProperty<DataType> : Property
{
    public DataType TypedValue
    {
        get { // Having problems here! }
        set { base.Value = value.ToString();}
    }
}

La question est donc:

Est-il un générique façon de convertir de chaîne vers un primitif?

Je n'arrive pas à trouver toute interface générique qui relie la conversion à travers le conseil d'administration (quelque chose comme ITryParsable aurait été l'idéal!).

Était-ce utile?

La solution

Je ne suis pas sûr de savoir si j'ai bien compris vos intentions correctement, mais nous allons voir si cela aide.

public class TypedProperty<T> : Property where T : IConvertible
{
    public T TypedValue
    {
        get { return (T)Convert.ChangeType(base.Value, typeof(T)); }
        set { base.Value = value.ToString();}
    }
}

Autres conseils

lubos hasko de la méthode échoue pour nullable.La méthode ci-dessous pour nullable.Je n'ai pas de venir avec elle, cependant.Je l'ai trouvé via Google: http://web.archive.org/web/20101214042641/http://dogaoztuzun.com/post/C-Generic-Type-Conversion.aspx Crédit de "Thon Toksoz"

L'utilisation de la première:

TConverter.ChangeType<T>(StringValue);  

La classe est ci-dessous.

public static class TConverter
{
    public static T ChangeType<T>(object value)
    {
        return (T)ChangeType(typeof(T), value);
    }

    public static object ChangeType(Type t, object value)
    {
        TypeConverter tc = TypeDescriptor.GetConverter(t);
        return tc.ConvertFrom(value);
    }

    public static void RegisterTypeConverter<T, TC>() where TC : TypeConverter
    {

        TypeDescriptor.AddAttributes(typeof(T), new TypeConverterAttribute(typeof(TC)));
    }
}

Pour de nombreux types (integer, double, DateTime, etc), il existe une méthode d'analyse statique.Vous pouvez l'invoquer l'aide de la réflexion:

MethodInfo m = typeof(T).GetMethod("Parse", new Type[] { typeof(string) } );

if (m != null)
{
    return m.Invoke(null, new object[] { base.Value });
}
TypeDescriptor.GetConverter(PropertyObject).ConvertFrom(Value)

TypeDescriptor est classe d'avoir de la méthode GetConvertor qui accepte un Type objet et ensuite vous pouvez appeler ConvertFrom méthode pour convertir le value pour que l'objet spécifié.

Vous pourriez peut-être utiliser une construction comme un classe de traits.De cette façon, vous aurez paramétré de la classe helper qui sait comment convertir une chaîne en valeur de son propre type.Ensuite, votre getter pourrait ressembler à ceci:

get { return StringConverter<DataType>.FromString(base.Value); }

Maintenant, je dois dire que mon expérience avec les types paramétrés est limitée à C++ et de ses modèles, mais j'imagine que c'est une façon de faire le même genre de chose à l'aide de C# génériques.

De vérifier la statique Nullable.GetUnderlyingType.- Si le sous-jacent est de type null, alors le paramètre de modèle n'est pas Nullable, et nous pouvons utiliser ce type directement - Si le type sous-jacent n'est pas null, alors utilisez le type sous-jacent dans la conversion.

Semble fonctionner pour moi:

public object Get( string _toparse, Type _t )
{
    // Test for Nullable<T> and return the base type instead:
    Type undertype = Nullable.GetUnderlyingType(_t);
    Type basetype = undertype == null ? _t : undertype;
    return Convert.ChangeType(_toparse, basetype);
}

public T Get<T>(string _key)
{
    return (T)Get(_key, typeof(T));
}

public void test()
{
    int x = Get<int>("14");
    int? nx = Get<Nullable<int>>("14");
}
public class TypedProperty<T> : Property
{
    public T TypedValue
    {
        get { return (T)(object)base.Value; }
        set { base.Value = value.ToString();}
    }
}

I utilisation de la conversion par l'intermédiaire d'un objet.C'est un peu plus simple.

J'ai utilisé lobos réponse et il fonctionne.Mais j'ai eu un problème avec la conversion de double en raison des paramètres de culture.J'ai donc ajouté

return (T)Convert.ChangeType(base.Value, typeof(T), CultureInfo.InvariantCulture);

Pourtant, une autre variante.Poignées Nullable, ainsi que des situations où la chaîne est nulle et T est pas nullable.

public class TypedProperty<T> : Property where T : IConvertible
{
    public T TypedValue
    {
        get
        {
            if (base.Value == null) return default(T);
            var type = Nullable.GetUnderlyingType(typeof(T)) ?? typeof(T);
            return (T)Convert.ChangeType(base.Value, type);
        }
        set { base.Value = value.ToString(); }
    }
}

Avec l'inspiration de l' Bob's réponse, ces extensions également en charge null la valeur de conversion et de toutes les primitives de conversion en arrière et quatrième.

public static class ConversionExtensions
{
        public static object Convert(this object value, Type t)
        {
            Type underlyingType = Nullable.GetUnderlyingType(t);

            if (underlyingType != null && value == null)
            {
                return null;
            }
            Type basetype = underlyingType == null ? t : underlyingType;
            return System.Convert.ChangeType(value, basetype);
        }

        public static T Convert<T>(this object value)
        {
            return (T)value.Convert(typeof(T));
        }
}

Exemples

            string stringValue = null;
            int? intResult = stringValue.Convert<int?>();

            int? intValue = null;
            var strResult = intValue.Convert<string>();
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top