Frage

Ich habe eine Klasse, die ich zum Speichern von „Eigenschaften“ für eine andere Klasse verwenden möchte.Diese Eigenschaften haben einfach einen Namen und einen Wert.Im Idealfall möchte ich etwas hinzufügen können getippt Eigenschaften, sodass der zurückgegebene „Wert“ immer den Typ hat, den ich haben möchte.

Der Typ sollte immer ein Primitiv sein.Diese Klasse ist eine Unterklasse einer abstrakten Klasse, die im Wesentlichen den Namen und den Wert als Zeichenfolge speichert.Die Idee dahinter ist, dass diese Unterklasse der Basisklasse eine gewisse Typsicherheit verleiht (und mir außerdem Konvertierungsaufwand erspart).

Also habe ich eine Klasse erstellt, die (ungefähr) so aussieht:

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

Die Frage ist also:

Gibt es eine „generische“ Möglichkeit, von einem String zurück in ein Grundelement zu konvertieren?

Ich kann anscheinend keine generische Schnittstelle finden, die die Konvertierung flächendeckend verknüpft (so etwas wie ITryParsable wäre ideal gewesen!).

War es hilfreich?

Lösung

Ich bin mir nicht sicher, ob ich Ihre Absichten richtig verstanden habe, aber mal sehen, ob das hilft.

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();}
    }
}

Andere Tipps

Die Methode von lubos hasko schlägt für Nullables fehl.Die folgende Methode funktioniert für Nullables.Ich bin allerdings nicht darauf gekommen.Ich habe es über Google gefunden: http://web.archive.org/web/20101214042641/http://dogaoztuzun.com/post/C-Generic-Type-Conversion.aspx Dank an „Tuna Toksoz“

Verwendung zuerst:

TConverter.ChangeType<T>(StringValue);  

Die Klasse ist unten.

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)));
    }
}

Für viele Typen (Integer, Double, DateTime usw.) gibt es eine statische Parse-Methode.Sie können es mithilfe von Reflection aufrufen:

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 ist eine Klasse mit einer Methode GetConvertor die a akzeptieren Type Objekt und dann können Sie anrufen ConvertFrom Methode zum Konvertieren der value für das angegebene Objekt.

Sie könnten möglicherweise ein Konstrukt wie a verwenden Merkmalsklasse.Auf diese Weise hätten Sie eine parametrisierte Hilfsklasse, die weiß, wie eine Zeichenfolge in einen Wert ihres eigenen Typs umgewandelt wird.Dann könnte Ihr Getter so aussehen:

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

Nun muss ich darauf hinweisen, dass meine Erfahrung mit parametrisierten Typen auf C++ und seine Vorlagen beschränkt ist, aber ich kann mir vorstellen, dass es eine Möglichkeit gibt, dasselbe mit C#-Generika zu erreichen.

Überprüfen Sie die Statik Nullable.GetUnderlyingType.– Wenn der zugrunde liegende Typ null ist, ist dies für den Vorlagenparameter nicht der Fall Nullable, und wir können diesen Typ direkt verwenden - wenn der zugrunde liegende Typ nicht null ist, dann verwenden Sie den zugrunde liegenden Typ in der Konvertierung.

Scheint bei mir zu funktionieren:

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();}
    }
}

Ich verwende die Konvertierung über ein Objekt.Es ist etwas einfacher.

Ich habe Lobos-Antwort verwendet und es funktioniert.Aber ich hatte ein Problem mit der Konvertierung von Doppel wegen der kulturellen Einstellungen.Also habe ich hinzugefügt

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

Noch eine Variante.Behandelt Nullables sowie Situationen, in denen die Zeichenfolge null und T null ist nicht nullbar.

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(); }
    }
}

Mit Inspiration von der BobAls Antwort unterstützen diese Erweiterungen auch die Nullwertkonvertierung und alle primitiven Konvertierungen hin und her.

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));
        }
}

Beispiele

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

            int? intValue = null;
            var strResult = intValue.Convert<string>();
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top