2008-11-07 4 views
60

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

public String Value { get; set; } 

public Type TheType { get; set; } 

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

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

+4

Общие свойства были бы приятными; Я думаю, что `var val = obj.Prop ` более краткий для поиска по типу, чем `obj.Prop [typeof (Type)]` или `obj.GetProp ()`. – Dan 2013-01-22 19:24:41

ответ

93

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

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 для преобразования, поскольку они позволяют классу определять собственный преобразователь.

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

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); 
    } 
} 
+0

Во втором примере класса «Foo» я озадачен: объявлено публичное свойство «theType»: «public Type TheType {get; set;}», но, похоже, не используется в коде. thanks, – BillW 2009-12-12 00:36:45

3

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

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

52

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

Смежные вопросы