2008-11-07 16 views
60

Mam klasę, która przechowuje wartość szeregową i typ. Chcę mieć właściwość/metoda zwracająca wartość już odlewane:Tworzenie ogólnej właściwości

public String Value { get; set; } 

public Type TheType { get; set; } 

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

Czy to możliwe w języku C#?

+4

Właściwości ogólne byłoby miło; Myślę, że 'var val = obj.Prop ' jest bardziej zwięzły dla wyszukiwania opartego na typie niż 'obj.Prop [typeof (Type)]' lub 'obj.GetProp ()'. – Dan

Odpowiedz

93

Jest to możliwe, jeśli klasa zawierający właściwość jest nazwą rodzajową, i zadeklarować właściwość pomocą parametru rodzajowego:

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

Alternatywą byłoby użyć metody rodzajowe Zamiast:

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

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

Możesz także użyć klas System.ComponentModel.TypeConverter do konwersji, ponieważ pozwalają klasie zdefiniować własny konwerter.

Edit: zauważ, że gdy wywołanie metody rodzajowe, należy określić parametr typu rodzajowego, ponieważ kompilator nie ma sposobu, aby go wywnioskować:

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

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

trzeba znać typ w czasie kompilacji . Jeśli nie znasz typu w czasie kompilacji, to musisz być przechowywanie go w object, w takim przypadku można dodać następującą właściwość do klasy Foo:

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

W drugim przykładzie klasy "Foo, jestem zaskoczony: właściwość publiczna" theType jest zadeklarowany: "public Type TheType {get; set;}", ale wydaje się nie być używane w kodzie. dzięki, – BillW

+0

Właściwość była w oryginalnym przykładzie. Właśnie go zostawiłem. – Brannon

+0

Kiedy próbuję rozwiązania Brannons, pojawia się błąd runtime, mówiąc, że obiekt, który przesyłam, musi implementować IConvertible. Czy zrobiłem coś złego, ponieważ wydaje się, że to łamacz transakcji, chyba że rzucisz klasę, w której mam dostępne źródło. – Keith

3

Nie wierzę przykład ty Podane tutaj jest możliwe. Typ CastedValue musi być zdefiniowany podczas kompilacji, co oznacza, że ​​nie może zależeć od wartości środowiska wykonawczego (wartość właściwości TheType).

EDYCJA: Rozwiązanie Brannona ma kilka dobrych pomysłów na to, jak sobie z tym poradzić, korzystając z ogólnej funkcji, a nie z właściwości.

52

Właściwości, zdarzenia, konstruktory itp. Nie mogą być ogólne - tylko metody i typy mogą być ogólne. Przez większość czasu to nie problem, ale zgadzam się, że czasami to jest ból. Odpowiedź Brannona daje dwa rozsądne rozwiązania.