Перечисления в общих ограничениях - PullRequest
2 голосов
/ 17 августа 2011

Я создал метод расширения для перечислений (перечислений) - назовите его, скажем, GetEnumSecondName

static string GetEnumSecondName(this Enum myEnumInstance)    {...}

Теперь у меня есть универсальный метод, который должен взять перечисление и вернуть все вторые имена для этого типа.

List<string> GetSecondNames<T : ?T:Enum ? >()
{ 
  // ...

  foreach T member in GetAllMembers<T>()
    // should work only for Enum instances
    resultList.Add(member.GetEnumSecondName()); 

  // ...
}

Есть ли обходной путь, чтобы это сделать?

Edit:

Как я понял (спасибо Джону Скиту), C # не поддерживает тонкие ограничения. Если есть какой-либо эксперт VB.NET, чтобы подтвердить, что «обычный» VB.NET также не поддерживает его. Спасибо.

1 Ответ

7 голосов
/ 17 августа 2011

Да, есть обходной путь.Вам может не понравиться это все же.Вы должны переписать IL, чтобы выразить требуемое ограничение - потому что CLR это позволяет, а C # - нет.(Компилятор соблюдает ограничение; он просто не позволяет вам выразить его в коде C #.)

У меня есть проект с именем Unconstrained Melody , который делает именно это, представленный в блоге .

К сожалению, вы не можете выразить это, и, возможно, это будет исправлено в следующей версии языка.На данный момент переписывание IL - это все, что я знаю.

РЕДАКТИРОВАТЬ: Я только что попробовал ограничение, которое вы хотели бы в VB:

Foo(Of T As { System.Enum, Structure }) (...)

И компилятор жалуетсяс:

error BC32061: 'Enum' cannot be used as a type constraint.

Так что нет, вы также не можете сделать это в VB.Как ни странно, на веб-странице об этой ошибке не упоминается ограничение ...

РЕДАКТИРОВАТЬ: Для тех, кто хочет играть с Unconstrained Melody, есть несколько шагов, необходимых для его получениярабочее:

  • Необходимо убедиться, что у вас есть соответствующий каталог SDK, как указано в ConstraintChanger\Program.cs.В частности, проверьте \Program Files\Microsoft SDKs\Windows, чтобы увидеть, какая у вас версия - и измените Program.cs соответствующим образом
  • . Критически, вам нужен каталог с именем "Rewritten" на верхнем уровне (то есть рядом с lib)
  • Если вы используете VS2010, вам нужно пройти обновление проекта в начале

После того, как все это правильно, вы можете просто нажать Ctrl-Shift-B и получить рабочую сборку. Не удаляйте и заменяйте ссылки на проекты - тестовая сборка должна ссылаться на переписанную, а не на проект, из которого она создана.

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

...