Эй, я думаю, что имею неверное представление здесь, но я не уверен, что является лучшим. Я хочу класс с членской переменной, которая может иметь любой тип, в зависимости от того, что необходимо в то время. До сих пор у меня есть что-то вроде этого:
public class ConfigSetting<T> {
private T value;
public T GetValue() {
return value;
}
public void ChangeValue() {
}
public ConfigSetting(string heading, string key) {
this.value = DerivedMethods.configsettings.SettingGroups[heading].Settings[key].RawValue;
}
}
Тип, возвращенный правой стороной 'this.value' строки, является строкой в настоящее время. Я знаю здесь, кажется, что у меня нет потребности использовать что-либо кроме строкового типа, но в конечном счете я разверну конструктора, такого, что 'this.value' мог быть строкой, интервалом, плаванием или bool.
Так или иначе в моем компиляторе говорится, "Не может преобразовать 'строку' в 'T'", таким образом, я предполагаю, что делаю что-то очень назад.
Спасибо.
] Ну, а какое преобразование вы ожидали, что оно будет применяться? Если вы ожидаете, что значение уже будет правильного типа, вы можете сделать: [
]. [object tmp = DerivedMethods.configsettings.SettingGroups[heading].Settings[key].RawValue;
this.value = (T) tmp;
]
[] Обратите внимание, что вы должны пройти через [] объект [
] либо неявно (как здесь), либо с помощью явного кастинга: [
this.value = (T)(object) DerivedMethods.configsettings... (etc);
]
[] Набор пересчетов, предусмотренных для общих типов, несколько ограничен. Но он должен работать, если исходное значение действительно верно. [
]] Вы сталкиваетесь с проблемами, потому что это не лучшее использование дженериков. Если параметр generic type может быть построен только четырьмя различными способами -- string, float, bool и int -- то это не очень []generic[]. Я ожидаю, что дженерик может быть []любым типом вообще []. [
] [] Если бы у меня была вещь, которая могла бы быть только одного из четырех типов, то я бы смоделировал ее так: [
] [abstract class ConfigSetting
{ /* shared code here */ }
class TextSetting : ConfigSetting
{ /* Code here to handle string settings */ }
class BooleanSetting : ConfigSetting
{ /* ...
]
[] и так далее. Я бы, вероятно, дал каждому из них внутренний конструктор, и сделал бы базовый класс в [] заводской [] для производных классов, используя заводской образец. [
] [] Используйте дженерики, только если ваше решение действительно [] дженериковое []. Как, например, []List
], может быть списком [] чего угодно []: чернила, строки, массивы, словари, функции, что угодно. Если моделируемая вещь имеет небольшое количество возможных типов, просто сделайте по одному для каждого типа.[
] Нужно бросить возвращаемую струну на []T[
]:[
public ConfigSetting(string heading, string key) {
this.value = (T)DerivedMethods.configsettings.SettingGroups[heading].Settings[key].RawValue;
}
] ] Я думаю, что не обязательно использовать дженерики, чтобы планировать заранее все возможные будущие сценарии, потому что в будущем вы, скорее всего, столкнетесь с крайними случаями и будете вынуждены модифицировать код независимо от этого. [
] [] Однако если у вас уже есть несколько сценариев, к которым подходит общий вариант, то вы можете извлечь выгоду из повторного использования логики сейчас и можете протестировать их все должным образом. [
] [] Вижу, другие уже дали кодовые ответы, так что я остановлюсь на этом. [
]] Я предполагаю, что [
] [DerivedMethods.configsettings.SettingGroups[heading].Settings[key].RawValue
]
[] это строка. [
] [] Нельзя присвоить строку [] this.value[
], потому что тип [] this.value[
] равен []T[
] и может быть чем угодно, например, типами, которым строки не присваиваются. [
] Одно из решений - удалить общий параметр и сделать строку [] значением [
], а затем предоставить различные способы доступа к ней, которые разобрали бы пулы, поплавки или что угодно по мере необходимости.[
public float GetFloatValue {
get { return float.Parse(this.value); }
}
// etc
] ]Похоже, что вы пытаетесь присвоить строку ([]configsettings.SettingsGroups[заголовок].Settings[ключ].RawValue[
]) родовому члену. Вам нужно будет предоставить какой-то способ преобразования строки в тип T -- обычно через кастинг. Например:[
this.value = (T)DerivedMethods.configsettings.SettingGroups[heading].Settings[key].RawValue;
] ] В этой строке: [
] [this.value = DerivedMethods.configsettings.SettingGroups[heading].Settings[key].RawValue;
]
[] вы устанавливаете вашу переменную типа T в строковое значение. Метод RawValue возвращает строку. Необходимо явно привести ее к типу T.[
]. [this.value = (T) (object) DerivedMethods.configsettings.SettingGroups[heading].Settings[key].RawValue;
]
[] Неужели это будут только значения без конструкторов? Вы можете сделать это явно и избежать кастинга объекта [] [], если захотите избежать этого по какой-то причине.[
].] Попробуй [
] [string strValue = DerivedMethods.configsettings.SettingGroups[heading].Settings[key].RawValue;
this.value = (T)Convert.ChangeType(strValue, typeof(T), CultureInfo.InvariantCulture)
]
[] если у вас есть значения конфигурации, сохраненные в виде строк, и вы хотите, чтобы они были преобразованы в правильный тип. Это работает только для большинства примитивных типов, таких как Int32, Double и т.д.[
].