Поскольку, пока конструктор не завершил выполнение, объект не полностью инстанцируют. Любые участники, на которых ссылается виртуальная функция, не могут быть инициализированы. В C++, когда Вы находитесь в конструкторе, this
только, относится к статическому типу конструктора, Вы находитесь в, а не фактический динамический тип объекта, который создается. Это означает, что вызов виртуальной функции даже не мог бы пойти, где Вы ожидаете его к.
Я предлагаю создать Dictionary
для отображения понятных имен на константы перечисления и использования обычных соглашений об именах в самих элементах.
enum Operation{ Equals, NotEquals, LessThan, GreaterThan };
var dict = new Dictionary<string, Operation> {
{ "Equals", Operation.Equals },
{ "Not Equals", Operation.NotEquals },
{ "Less Than", Operation.LessThan },
{ "Greater Than", Operation.GreaterThan }
};
var op = dict[str];
В качестве альтернативы, если вы хотите придерживаться вашего текущего метода, вы можете сделать (чего я не рекомендую делать):
var op = (Operation)Enum.Parse(typeof(Operation), str.Replace(' ', '_'));
Зачем использовать другой способ: преобразовать перечисление в строку?
Просто сгенерируйте элементы поля со списком из перечисления.
в C # вы можете добавлять методы расширения к перечисляемым типам. Видеть http://msdn.microsoft.com/en-us/library/bb383974.aspx
Этот подход можно использовать для добавления методов toString (Operation op), fromString (String str) и toLocalizedString (Operation op) к вашим типам перечисления. Метод, который вы используете для поиска конкретной строки, зависит от вашего приложения и должен соответствовать тому, что вы делаете в подобных случаях. Использование словаря, как предлагали другие, кажется хорошим первым подходом, если вам не нужна полная локализация в вашем приложении.
Если вы хотите, чтобы test1.py оставался исполняемым с той же функциональностью, что и при
string someInputText;
var operation = (Operation)Enum.Parse(typeof(Operation), someInputText.Replace(" ", "_"));
Вы можете использовать метод Parse:
Operarion operation = (Operation)Enum.Parse(typeof(Operation), "Not_Equals");
Некоторые примеры здесь
Either create a dedicated mapper using a dictionary (per Mehrdad's answer) or implement a TypeConverter.
Your custom TypeConverter could either replace " " -> "_"
(and vice versa) or it could reflect the enumeration and use an attribute for determining the display text of the item.
enum Operation
{
[DisplayName("Equals")]
Equals,
[DisplayName("Not Equals")]
Not_Equals,
[DisplayName("Less Than")]
Less_Than,
[DisplayName("Greater Than")]
Greater_Than
};
public class OperationTypeConverter : TypeConverter
{
private static Dictionary<string, Operation> operationMap;
static OperationTypeConverter()
{
BindingFlags bindingFlags = BindingFlags.Static | BindingFlags.GetField
| BindingFlags.Public;
operationMap = enumType.GetFields(bindingFlags).ToDictionary(
c => GetDisplayName(c)
);
}
private static string GetDisplayName(FieldInfo field, Type enumType)
{
DisplayNameAttribute attr = (DisplayNameAttribute)Attribute.GetCustomAttribute(typeof(DisplayNameAttribute));
return (attr != null) ? attr.DisplayName : field.Name;
}
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
string stringValue = value as string;
if (stringValue != null)
{
Operation operation;
if (operationMap.TryGetValue(stringValue, out operation))
{
return operation;
}
else
{
throw new ArgumentException("Cannot convert '" + stringValue + "' to Operation");
}
}
}
}
This implementation could be improved in several ways: