В nameof
документации конкретно сказано, что то, что вы хотите сделать, к сожалению, запрещено. :
Поскольку синтаксически аргумент должен быть выражением, есть много запрещенных вещей, которые бесполезно перечислять. Следует упомянуть следующее, вызывающее ошибки: предопределенные типы (например, int
или void
), типы, допускающие значение NULL (Point?
), типы массивов (Customer[,]
), типы указателей (Buffer*
), квалифицированные псевдонимы (A::B
) и непривязанные универсальные типы. типы (Dictionary<,>
), символы предварительной обработки (DEBUG
) и метки (loop:
).
Лучшее, что вы можете сделать, это указать Bar
в интерфейсе и использовать nameof(IFoo.Bar)
. Конечно, это не вариант, если Bar
включает в свою подпись что-то, связанное с T
(как в этом конкретном случае).
Другой вариант — создать интерфейс, в котором каждое T
заменено на object
. Затем конкретный тип явно реализует интерфейс, а также реализует универсальные версии тех же методов.
У этого есть несколько недостатков:
- Увеличенная поверхность API
- Более сложный и подверженный ошибкам рефакторинг
- Потеря безопасности типа во время компиляции, потому что вызывающая сторона может использовать интерфейс
object
.
Это, вероятно, не оправдано только для использования nameof
, но в некоторых случаях эта стратегия имеет смысл по другим причинам. В таких случаях возможность использовать nameof
будет просто удобным бонусом.
person
31eee384
schedule
19.11.2015