Создание общей собственности

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

public String Value { get; set; }

public Type TheType { get; set; }

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

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

Общие свойства были бы хороши; Я думаю, что var val = obj.Prop<Type> более лаконичен для поиска по типу, чем obj.Prop[typeof(Type)] или obj.GetProp<Type>().

Dan Lugg 22.01.2013 23:24
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
74
1
91 599
3

Ответы 3

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

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;}», но, похоже, не используется в коде. Благодарность,

BillW 12.12.2009 03:36

Имущество было в оригинальном примере. Я просто оставил это.

Brannon 14.12.2009 12:33

Когда я пробую решение Браннона, я получаю сообщение об ошибке выполнения, в котором говорится, что объект, который я кастую, должен реализовывать IConvertible. Я сделал что-то не так, потому что это кажется нарушением сделки, если только я не приведу класс, в котором у меня есть доступный источник.

Keith 19.02.2012 15:38

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

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

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

Другие вопросы по теме