Franco Tiveron
Franco Tiveron

Reputation: 2916

Using nameof for a recursive generic type's property

I have the following class

public abstract class Result<TResult, TData> where TResult : Result<TResult, TData>
{
    public virtual TData Data { get; private set; }
}

How can I use nameof on the Data property?

It tried some options but got compilation errors

nameof(Result<object, object>.Data)

Error   CS0311  
The type 'object' cannot be used as type parameter 'TResult' in the generic type or method 
'Result<TResult, TData>'. There is no implicit reference conversion from 'object' to 
'Result<object, object>'

UPDATE To better specify:

I did not write the class in the first snippet, but I have to use it as it is. I need to use reflection to get a PropertyInfo instance for the Data property. I can do it by calling GetProperty("Data"), but I prefer to avoid strings in case the name property is renamed with the Visual Studio Refactoring (for example from Data to Content). I cannot use nameof(Data) and I am in a different context that doesn't know about the Data property in that class.

As such, I would call GetProperty(nameof({whatever}.Data)). Of course, if not possible I would use the string. But if there is a way, I would like to know it.

Upvotes: 0

Views: 324

Answers (1)

Peter Duniho
Peter Duniho

Reputation: 70701

Unfortunately, the nameof operator does not work with unbound generic types. E.g. you'd like to be able to write nameof(Result<,>.Data), just like you can today write something like typeof(Result<,>). So you would need to specify type parameters when trying to get the nameof(Result<TResult, TData>.Data) value.

Which you've tried, but you provided object as the type parameter for both parameters, even though your generic type constrains TResult as being derived from Result<TResult, TData>. The type object doesn't meet the constraint, so that can't possibly work. Hence the compiler error.

Obviously, if you can provide any type that does meet the constraint, that would solve the compiler error and allow you to use the nameof operator. There's not enough information in your question to know whether that's an option in your specific scenario.

I agree with this comment that you would probably be better off asking a different question, one which takes a step back and explains how you arrived at feeling you needed this syntax in the first place. It's not clear what the broader goal you're trying to accomplish is, where you don't have known type parameters to use for this expression. Typically, code outside of the generic type that wants to make use of the generic type, would actually know the type parameters it intends to use with the generic type.

Note that in the context of the generic type itself, you can refer to the property without knowing the exact type parameters, since the property identifier does not need qualification. E.g. nameof(Data) would work, for any code that's actually in the generic class Result<TResult, TData>. Whether that helps in your specific scenario is unclear from the information provided so far.

Upvotes: 2

Related Questions