77

I have a class that stores a serialized value and a type. I want to have a property/method returning the value already casted:

public String Value { get; set; }

public Type TheType { get; set; }

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

Is this possible in C#?

EBarr
  • 11,826
  • 7
  • 63
  • 85
  • 4
    Generic properties would be nice; I think `var val = obj.Prop` is more succinct for a type-based lookup than `obj.Prop[typeof(Type)]` or `obj.GetProp()`. – Dan Lugg Jan 22 '13 at 19:24

3 Answers3

112

It's possible if the class containing the property is generic, and you declare the property using the generic parameter:

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

An alternative would be to use a generic method instead:

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

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

You can also use the System.ComponentModel.TypeConverter classes to convert, since they allow a class to define it's own converter.

Edit: note that when calling the generic method, you must specify the generic type parameter, since the compiler has no way to infer it:

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

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

You have to know the type at compile time. If you don't know the type at compile time then you must be storing it in an object, in which case you can add the following property to the Foo class:

public object ConvertedValue {
    get {
        return Convert.ChangeType(Value, Type);
    }
}
Quassnoi
  • 413,100
  • 91
  • 616
  • 614
Brannon
  • 25,687
  • 5
  • 39
  • 44
  • In the second example of class 'Foo, I am baffled : a public property 'theType is declared : "public Type TheType { get; set; }" but appears not to be used in the code. thanks, – BillW Dec 12 '09 at 00:36
  • The property was in the original example. I just left it in. – Brannon Dec 14 '09 at 09:33
  • When I try Brannons solution I get a runtime error saying the object I am casting must implement IConvertible. Have I done something wrong because this seems like a deal breaker unless casting a class where I have the source available. – Keith Feb 19 '12 at 11:38
61

Properties, events, constructors etc can't be generic - only methods and types can be generic. Most of the time that's not a problem, but I agree that sometimes it's a pain. Brannon's answer gives two reasonable workarounds.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
5

I don't believe the example you've given here is possible. The type of CastedValue has to be defined at compile time, which means it can't depend on a runtime value (the value of the TheType property).

EDIT: Brannon's solution has some good ideas for how to handle this using a generic function rather than a property.

Charlie
  • 44,214
  • 4
  • 43
  • 69