Ich habe eine Klasse, die einen serialisierten Wert und einen Typ speichert. Ich möchte eine Eigenschaft/Methode haben, die den bereits gegossenen Wert zurückgibt:Erstellen einer generischen Eigenschaft
Ist dies in C# möglich?
Ich habe eine Klasse, die einen serialisierten Wert und einen Typ speichert. Ich möchte eine Eigenschaft/Methode haben, die den bereits gegossenen Wert zurückgibt:Erstellen einer generischen Eigenschaft
Ist dies in C# möglich?
Es ist möglich, wenn die Klasse die Eigenschaft ist generisch, und erklären Sie, die Eigenschaft mit dem generischen Parameter enthält:
class Foo<TValue> {
public string Value { get; set; }
public TValue TypedValue {
get {
return (TValue)Convert.ChangeType(Value, typeof(TValue));
}
}
}
Eine Alternative wäre, zu verwenden, um eine generische Methode statt:
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 die Klassen System.ComponentModel.TypeConverter
zum Konvertieren verwenden, da sie einer Klasse erlauben, ihren eigenen Konverter zu definieren.
bearbeiten: beachten Sie, dass, wenn die generische Methode aufrufen, können Sie die generischen Typparameter angeben müssen, da der Compiler keine Möglichkeit, es zu schließen, hat:
Foo foo = new Foo();
foo.Value = "100";
foo.Type = typeof(int);
int c = foo.CastValue<int>();
Sie die Art zum Zeitpunkt der Kompilierung wissen müssen . Wenn Sie nicht die Art zum Zeitpunkt der Kompilierung wissen, dann müssen Sie es in diesem Fall in einem object
, Speichern, Sie die folgende Eigenschaft auf die Foo
Klasse kann hinzufügen:
public object ConvertedValue {
get {
return Convert.ChangeType(Value, Type);
}
}
Im zweiten Beispiel der Klasse 'Foo, bin ich verblüfft: eine öffentliche Eigenschaft' theType wird deklariert: "public Typ TheType {Get; Set;}" aber scheint nicht im Code verwendet werden. Danke, – BillW
Das Anwesen war im ursprünglichen Beispiel. Ich habe es einfach gelassen. – Brannon
Wenn ich Brannons Lösung versuche, bekomme ich einen Laufzeitfehler, der besagt, dass das Objekt, das ich werfe, IConvertible implementieren muss. Habe ich etwas falsch gemacht, weil dies wie ein Deal-Breaker aussieht, es sei denn, ich werfe eine Klasse aus, in der ich die Quelle verfügbar habe. – Keith
Ich glaube nicht, das Beispiel, das Sie hier gegeben ist möglich. Der Typ von CastedValue muss zur Kompilierzeit definiert werden, was bedeutet, dass er nicht von einem Laufzeitwert (dem Wert der TheType-Eigenschaft) abhängen kann.
EDIT: Brannon Lösung hat einige gute Ideen für den Umgang mit diesem mit einer generischen Funktion anstelle einer Eigenschaft.
Eigenschaften, Ereignisse, Konstruktoren usw. können nicht generisch sein - nur Methoden und Typen können generisch sein. Die meiste Zeit ist das kein Problem, aber ich stimme zu, dass es manchmal ein Schmerz ist. Brannons Antwort gibt zwei vernünftige Lösungen.
Generische Eigenschaften wären nett; Ich denke, 'var val = obj.Prop' ist prägnanter für eine typbasierte Suche als 'obj.Prop [typeof (Type)]' oder 'obj.GetProp ()'. –
Dan