Создание родового имущества

У меня есть класс, который хранит сериализованное значение и тип. Я хочу, чтобы свойство/метод возвращало уже запущенное значение:

public String Value { get; set; }

public Type TheType { get; set; }

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

Возможно ли это в С#?

Ответ 1

Возможно, если класс, содержащий свойство, является общим, и вы объявляете свойство с помощью общего параметра:

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

Альтернативой может быть использование общего метода:

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

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

Вы также можете использовать классы System.ComponentModel.TypeConverter для преобразования, поскольку они позволяют классу определять собственный конвертер.

Изменить: обратите внимание, что при вызове общего метода вы должны указать параметр универсального типа, поскольку компилятор не имеет возможности сделать это:

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

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

Вы должны знать тип во время компиляции. Если вы не знаете тип во время компиляции, вы должны сохранить его в object, и в этом случае вы можете добавить следующее свойство в класс Foo:

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

Ответ 2

Свойства, события, конструкторы и т.д. не могут быть общими - только методы и типы могут быть общими. Большую часть времени это не проблема, но я согласен, что иногда это боль. Ответ Брэннона дает два разумных решения.

Ответ 3

Я не верю, что приведенный здесь пример возможен. Тип CastedValue должен быть определен во время компиляции, что означает, что он не может зависеть от значения времени выполнения (значение свойства TheType).

EDIT: решение Браннона имеет несколько хороших идей для того, как справиться с этим, используя универсальную функцию, а не свойство.