ninjaef Ответов: 1

C# : "расширить" тип перечисления во время выполнения


Итак, у меня есть это довольно большое приложение, которое использует перечисление TagType. Использование TagType широко распространено в кодовой базе. Я модифицирую код, чтобы позволить пользователям добавлять теги, другими словами, "расширять" перечисление, так сказать, во время выполнения

Приложение представляет собой интерфейс базы данных. Мы не можем изменить кодовую базу. Мы не можем внести существенные изменения, чтобы сделать кодовую базу "непроверенной". Поэтому мы не можем реализовать то, что можно было бы считать "лучшей практикой". Нам просто нужен способ "расширить" тип-во время выполнения - так, чтобы кодовая база продолжала функционировать "как была", но с возможностью добавить небольшой фрагмент кода, который будет реализовывать-любыми возможными средствами - это изменение

текущее определение TagType таково

public enum TagType {
   __RESERVED__ = 0,
   __Raised__   = 1,
   __Closed__   = 2 
}


но нам нужен какой-то способ "расширения" этих значений во время выполнения , чтобы функциональность кодовой базы оставалась работоспособной, то есть там, где код может, например, тестироваться:
if (localTag == __Raised__)
   db.Search(localTag)


и так далее...

ваше решение не обязательно должно быть перечислением, TagType находится в своем собственном файле, и мы можем изменить реализацию TagType на что угодно при условии, что остальная часть кодовой базы компилируется и запускается.

Кстати, код должен быть переносимым и не делать предположений о O/S - так что решения, основанные на отражении, могут оказаться невозможными.

Что я уже пробовал:

Я просматриваю страницы google, чтобы найти множество решений для отдельных ситуаций, но, прочитав их, ни один из них, которые я прочитал, не соответствует этому требованию. Поэтому, пожалуйста, если вы намерены направить меня в google, то, пожалуйста, я могу очень вежливо попросить вас пойти помочь какому-нибудь другому члену codeproject, а не писать здесь.

Кроме того, это выглядело как хорошее решение, однако оно зависит от сборок, и я не хотел навязывать код конкретной ОС.

ТПС://сайте StackOverflow.ком/вопросы/857414/динамически создать-Ан-перечисление

F-ES Sitecore

Если код не знает о ваших расширенных значениях перечисления, когда он был скомпилирован, то он ничего не может с ними сделать, так что это требование немного бессмысленно.

Рефакторинг кода, чтобы использовать что-то другое, кроме перечисления, использовать коллекцию значений имени, словарь или что-то еще, что соответствует этому требованию. Сказать, что вы не можете изменить кодовую базу, все равно что сказать, что вы хотите сделать омлет, не разбив яиц.

ninjaef

Неверное предположение

Кодовая база ориентирована на Плагины, хотя плагины могут быть довольно большими с точки зрения SLoC. Это плагин, за который мы несем ответственность. Таким образом," интерпретация "" перечислений " выполняется в плагине, но распространяется через обратные вызовы. Я не хочу вдаваться в дизайн , поэтому я намеренно попросил помощи на очень конкретном примере, и именно поэтому я также не хотел вступать в дискуссию об архитектуре и модели дизайна, которую мы здесь почти не контролируем.

1 Ответов

Рейтинг:
2

Prifti Constantine

Одним из способов было бы:

 public enum TagType {
   __RESERVED__ = 0,
   __Raised__   = 1,
   __Closed__   = 2 
}
TagType AnotherEnumValue = (TagType)3;

Вы можете позже проверить это как:
if (SomeValue == (TagType)3{

}

Надеюсь, это вам поможет!


ninjaef

просто и идеально. даст этому ход, но выглядит как элегантное решение для расширения существующей функциональности.

Хотя два вопроса:-
1.перечисление.Метод isdefined() требует аргумента. Есть ли простой способ проверить, определено ли значение int в перечислении?
2. TagType AnotherEnumValue = (TagType)3 не будет "добавлять "" AnotherEnumValue " в диапазон перечислений - другими словами, IsDefined(3) даст False? Как мы можем преодолеть это?

Prifti Constantine

Вы могли бы использовать некоторое отражение в этой ситуации, чтобы вы могли получить тип конкретного значения перечисления и проверить его там, где вы хотите! Если вам нужно дополнительное объяснение, я могу его предоставить...хотя вы можете использовать только TypeOf (). Это временно добавит нужное значение внутри перечисления до тех пор, пока проект остается во время выполнения... Он не будет генерировать код для вас... В этой ситуации "пользователь F-ES Sitecore" прав.. Вы могли бы использовать какой-то тип коллекции, который более удобен в этих ситуациях! Рад помочь! Это действительно поможет, если вы подтвердите ответ! С наилучшими пожеланиями!

ninjaef

пример того, как я мог бы использовать коллекцию, был бы хорош?

используя пример TagType выше?

Prifti Constantine

Чего именно вы пытаетесь достичь с помощью этого перечисления?

ninjaef

как объяснено в ОП

не уверен, чего ты не понимаешь? извиняюсь.

но это просто

у нас есть перечисление Tagtype, используемое в большом количестве кода. нам нужно ввести механизм, позволяющий добавлять список перечислений во время выполнения, сохраняя при этом ссылки кода на тип тега, такие как

Если (а == TagType.someEnum)...

простой

Prifti Constantine

Поскольку вам нужно добавить больше значений в перечисление во время выполнения, то, вероятно, перечисление-не самая лучшая идея... Я бы рекомендовал список с вашими предпочтительными значениями внутри и получать их во время выполнения с каким-то событием . Вы можете получить значения с помощью запросов Linq. Я просто нахожу идею коллекции лучше, поскольку коллекция более управляема и гибка, чем перечисления..

Prifti Constantine

Вы могли бы создать объект, который обладает свойствами : __отведенные__ = 0,
__Подняла__= 1,__Закрыт__ = 2.
попробуйте добавить их в каком-то мероприятии:
List lst=новый список();
LST. add (новый объект {__RESERVED_ _ = 0});
lst. add (новый объект {__Raised_ _ = 1});
lst. add (новый объект {__Closed_ _ = 2});
Вы могли бы попробовать получить их вот так:
Используйте var перед переменной, так как это всегда лучше, когда вы хотите добавить или получить что-то во время выполнения..
Var listQuery =
из значений в lst
где объект.Имя = " _ _ Закрыто__"
выберите студента.Ценность;

listQuery будет удерживать указанное вами значение для того, чтобы использовать его.
Я очень надеюсь, что это поможет вам. Я не мог быть более конкретным, так как перечисление было единственной поставляемой вещью. С наилучшими пожеланиями!

ninjaef

извиняюсь

Я не понимаю, в чем дело...

который...

TagType широко используется в коде, который мы не можем изменить. например...

if (tag = TagType. _ _ RESERVED__)....

переключатель (тег)
__Закрытый__ :......

и так далее

мы не можем изменить эту ссылку на объект

мы, конечно, не можем создать список нового типа и перекодировать его

Prifti Constantine

Что ж, тогда вам просто нужно придерживаться решения... Не могу придумать способ, который использует перечисления вместе с коллекциями. Может быть, я и ошибаюсь, но я тоже нигде его не видел.. Если ваша проблема заключается только в добавлении дополнительных значений во время выполнения, то она решена. Если нет, то просто сохраните (TagType) 3 во временной переменной и затем используйте ее соответствующим образом.
var temp = (TagType)3;

ninjaef

возможно, это и есть решение

но я не понимаю, что здесь происходит, поэтому не знаю, как применить эту технику к моей проблеме

но, похоже, я могу создавать методы класса во время выполнения

чтобы я мог создать поле Tagtype.newEnum?

https://stackoverflow.com/a/25256727/7990543


или то, что об объекте расширенного...
https://msdn.microsoft.com/en-us/magazine/ff796227.aspx

но, рыдая, мне нужна помощь, чтобы понять это