0

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.

Franco Tiveron
  • 2,364
  • 18
  • 34
  • This feels like a XY Problem (https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem)? What string are you hoping to generate, and why? – mjwills Sep 18 '20 at 02:20
  • 2
    Your `where` on the generic type restricts `TResult` to be a `Result`. The `object` type doesn't match that restriction – Flydog57 Sep 18 '20 at 02:28
  • 1
    @OlivierRogier - No, this kind of structure is perfectly fine. Try this: `public class Foo : Result { }`. You can create a `Foo` instance with no problem. – Enigmativity Sep 18 '20 at 03:13
  • Please don't change your question after it's been answered. It is disrespectful of the Stack Overflow community to present a moving target. The question you asked was answered. Adding constraints after the fact alters the specifics of the question in ways that often invalidate the effort already put into answering the question. If you want advice about the broader scenario, post a new question, and explain everything about that scenario, including why you need to use reflection, and why you have to access the property by specific name instead of by selecting it from the list of properties. – Peter Duniho Sep 18 '20 at 15:48

1 Answers1

2

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.

Peter Duniho
  • 68,759
  • 7
  • 102
  • 136
  • eg `static string Name => nameof(Result.Data)`, now external classes can refer to `DerivedResult.Name`. – Jeremy Lakeman Sep 18 '20 at 03:03
  • @JeremyLakeman: not without type parameters they can't. At some point, the code retrieving the name will have to provide actual types, so that the generic type winds up constructed. And then they will wind up running into exactly the same issue in the original question. – Peter Duniho Sep 18 '20 at 03:04