У меня есть класс, в котором хранятся сериализованное значение и тип. Я хочу, чтобы свойство / метод возвращали уже введенное значение:
public String Value { get; set; }
public Type TheType { get; set; }
public typeof(TheType) CastedValue { get { return Convert.ChangeType(Value, typeof(_Type)); }
Возможно ли это в C#?





Это возможно, если класс, содержащий свойство, является универсальным, и вы объявляете свойство с помощью универсального параметра:
class Foo<TValue> {
public string Value { get; set; }
public TValue TypedValue {
get {
return (TValue)Convert.ChangeType(Value, typeof(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);
}
}
Во втором примере класса Foo я сбит с толку: объявлено публичное свойство theType: «public Type TheType {get; set;}», но, похоже, не используется в коде. Благодарность,
Имущество было в оригинальном примере. Я просто оставил это.
Когда я пробую решение Браннона, я получаю сообщение об ошибке выполнения, в котором говорится, что объект, который я кастую, должен реализовывать IConvertible. Я сделал что-то не так, потому что это кажется нарушением сделки, если только я не приведу класс, в котором у меня есть доступный источник.
Я не верю, что приведенный вами пример возможен. Тип CastedValue должен быть определен во время компиляции, что означает, что он не может зависеть от значения времени выполнения (значения свойства TheType).
Обновлено: В решении Браннона есть несколько хороших идей о том, как справиться с этим, используя общую функцию, а не свойство.
Свойства, события, конструкторы и т. д. Не могут быть универсальными - универсальными могут быть только методы и типы. В большинстве случаев это не проблема, но я согласен, что иногда это неприятно. Ответ Брэннона дает два разумных обходных пути.
Общие свойства были бы хороши; Я думаю, что
var val = obj.Prop<Type>более лаконичен для поиска по типу, чемobj.Prop[typeof(Type)]илиobj.GetProp<Type>().