Вы не должны добавить другого оператора.Вы уже определили реальную проблему:
Проверка кода показывает, что атрибут экземпляров класса StringEnum никогда не заполняется.
Это потому, что ничто никогда не заставляетDerivedStringEnum
класс для инициализации.Вы никогда не обращаетесь к чему-либо, что будет заставлять его инициализироваться.Если вы сделаете это, добавив статический конструктор (чтобы избежать оптимизации инициализации типа) и статический метод, который затем вызывается для принудительной инициализации, он работает нормально:
public class DerivedStringEnum : StringEnum
{
// Other members as before.
static DerivedStringEnum()
{
}
public static void ForceInit()
{
}
}
class Test
{
static void Main()
{
string s = "EnumValue1";
DerivedStringEnum.ForceInit();
DerivedStringEnum e = (DerivedStringEnum) s;
Console.WriteLine(e); // EnumValue1
}
}
Это не то, что я бы порекомендовалделать - мне не нравится, когда состояние базового класса эффективно зависит от того, был ли инициализирован какой-либо производный тип - но это действительно объясняет ...
Обратите внимание, что ответ Андраса работает (или, по крайней мере, может работать, хотя я не думаю, что это гарантировано), потому что, вызывая оператор, объявленный в производном типе, вы могли бы закончить инициализацию типа.Возможно, вы этого не сделаете - инициализация типа может быть очень ленивой .Я полагаю, что вам действительно нужно использовать поле внутри оператора (до вызова оператора базового преобразования), чтобы действительно вызвать инициализацию.
С просто Оператор StringEnum
в соответствии с исходным вопросом, эта строка:
DerivedStringEnum e = (DerivedStringEnum) s;
скомпилирована как для вызова пользовательского оператора , так и cast:
IL_000d: ldloc.0
IL_000e: call class StringEnum StringEnum::op_Explicit(string)
IL_0013: castclass DerivedStringEnum