it-swarm.com.de

Erstellen einer generischen Eigenschaft

Ich habe eine Klasse, die einen serialisierten Wert und einen Typ speichert. Ich möchte eine Eigenschaft/Methode haben, die den bereits übertragenen Wert zurückgibt:

public String Value { get; set; }

public Type TheType { get; set; }

public typeof(TheType) CastedValue { get { return Convert.ChangeType(Value, typeof(_Type)); }

Ist das in C # möglich?

65
fer

Es ist möglich, dass die Klasse, die die Eigenschaft enthält, generisch ist und Sie die Eigenschaft mit dem generischen Parameter deklarieren:

class Foo<TValue> {
    public string Value { get; set; }
    public TValue TypedValue {
        get {
            return (TValue)Convert.ChangeType(Value, typeof(TValue));
        }
    }
}

Eine Alternative wäre, stattdessen eine generische Methode zu verwenden:

class Foo {
    public string Value { get; set; }
    public Type TheType { get; set; }

    public T CastValue<T>() {
         return (T)Convert.ChangeType(Value, typeof(T));
    }
}

Sie können auch das System.ComponentModel.TypeConverter Klassen, die konvertiert werden sollen, da sie es einer Klasse ermöglichen, ihren eigenen Konverter zu definieren.

Edit: Beachten Sie, dass Sie beim Aufrufen der generischen Methode den generischen Typparameter angeben müssen, da der Compiler nicht darauf schließen kann:

Foo foo = new Foo();
foo.Value = "100";
foo.Type = typeof(int);

int c = foo.CastValue<int>();

Sie müssen den Typ beim Kompilieren kennen. Wenn Sie den Typ zur Kompilierungszeit nicht kennen, müssen Sie ihn in einem object speichern. In diesem Fall können Sie der Klasse Foo die folgende Eigenschaft hinzufügen:

public object ConvertedValue {
    get {
        return Convert.ChangeType(Value, Type);
    }
}
101
Brannon

Eigenschaften, Ereignisse, Konstruktoren usw. können nicht generisch sein - nur Methoden und Typen können generisch sein. Meistens ist das kein Problem, aber ich stimme zu, dass es manchmal ein Schmerz ist. Brannons Antwort bietet zwei sinnvolle Umgehungsmöglichkeiten.

54
Jon Skeet

Ich glaube nicht, dass das Beispiel, das Sie hier gegeben haben, möglich ist. Der Typ von CastedValue muss zur Kompilierungszeit definiert werden. Dies bedeutet, dass er nicht von einem Laufzeitwert (dem Wert der TheType-Eigenschaft) abhängen kann.

BEARBEITEN: Brannons Lösung hat einige gute Ideen, wie dies mit einer generischen Funktion anstelle einer Eigenschaft gehandhabt werden kann.

3
Charlie