Een generieke eigenschap maken

Ik heb een klasse die een geserialiseerde waarde en een type opslaat. Ik wil een eigenschap/methode hebben die de reeds gecaste waarde retourneert:

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

Is dit mogelijk in C#?


Antwoord 1, autoriteit 100%

Het is mogelijk als de klasse die de eigenschap bevat generiek is en u de eigenschap declareert met behulp van de generieke parameter:

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

Een alternatief zou zijn om in plaats daarvan een generieke methode te gebruiken:

class Foo {
    public string Value { get; set; }
    public Type TheType { get; set; }
    public T CastValue<T>() {
         return (T)Convert.ChangeType(Value, typeof(T));
    }
}

Je kunt ook de klassen System.ComponentModel.TypeConvertergebruiken om te converteren, omdat ze een klasse in staat stellen zijn eigen converter te definiëren.

Bewerken: merk op dat wanneer u de generieke methode aanroept, u ​​de generieke type parameter moet specificeren, aangezien de compiler deze niet kan afleiden:

Foo foo = new Foo();
foo.Value = "100";
foo.Type = typeof(int);
int c = foo.CastValue<int>();

Je moet het type weten tijdens het compileren. Als u het type niet kent tijdens het compileren, moet u het opslaan in een object, in welk geval u de volgende eigenschap kunt toevoegen aan de klasse Foo:

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

Antwoord 2, autoriteit 55%

Eigenschappen, gebeurtenissen, constructors enz. kunnen niet generiek zijn – alleen methoden en typen kunnen generiek zijn. Meestal is dat geen probleem, maar ik ben het ermee eens dat het soms lastig is. Het antwoord van Brannon geeft twee redelijke oplossingen.


Antwoord 3, autoriteit 5%

Ik geloof niet dat het voorbeeld dat je hier hebt gegeven mogelijk is. Het type CastedValue moet tijdens het compileren worden gedefinieerd, wat betekent dat het niet afhankelijk kan zijn van een runtime-waarde (de waarde van de eigenschap TheType).

EDIT: Brannons oplossing heeft een aantal goede ideeën om hiermee om te gaan door een generieke functie te gebruiken in plaats van een eigenschap.

Other episodes