The nameof
documentation specifically says that what you want to do is disallowed, unfortunately:
Because the argument needs to be an expression syntactically, there
are many things disallowed that are not useful to list. The following
are worth mentioning that produce errors: predefined types (for
example, int
or void
), nullable types (Point?
), array types
(Customer[,]
), pointer types (Buffer*
), qualified alias (A::B
), and
unbound generic types (Dictionary<,>
), preprocessing symbols (DEBUG
),
and labels (loop:
).
The best you can probably do is specify Bar
in an interface, and use nameof(IFoo.Bar)
. Of course, that isn't an option if Bar
includes something related to T
in its signature (like in this specific case).
Another option is to create an interface where each T
is replaced with object
. Then the concrete type implements the interface explicitly, also implementing generic versions of the same methods.
This has a few downsides:
- Larger API surface
- More difficult and error-prone refactoring
- Losing compile-time type safety because a caller might use the
object
interface.
This probably isn't justifiable just to use nameof
, but in some cases this strategy makes sense for other reasons. In those cases, being able to use nameof
would just be a convenient bonus.