Створення родової властивості


74

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

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<Type>, що для пошуку на основі типу більш стислим, ніж obj.Prop[typeof(Type)]або obj.GetProp<Type>().
Dan Lugg

Відповіді:


106

Це можливо, якщо клас, що містить властивість, є загальним, і ви оголошуєте властивість за допомогою загального параметра:

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 оголошено: "загальнодоступний тип TheType {get; set;}", але, здається, не використовується в коді. спасибі,
BillW

Властивість була в оригінальному прикладі. Я щойно залишив це.
Бреннон,

Коли я пробую рішення Brannons, я отримую помилку під час виконання, кажучи, що об'єкт, який я передаю, повинен реалізувати IConvertible. Чи зробив я щось не так, тому що це здається переривачем угод, якщо не кинути клас, де у мене є джерело.
Кіт,

59

Властивості, події, конструктори тощо не можуть бути загальними - лише методи та типи можуть бути загальними. Здебільшого це не проблема, але я згоден, що іноді це біль. Відповідь Бреннона дає два обґрунтовані способи вирішення.


5

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

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.