3

Considering the following implementation of a generic, abstract class:

public abstract class BaseRequest<TGeneric> : BaseResponse where TRequest : IRequestFromResponse
{
    public TGeneric Request { get; set; }
}

Is there any chance to get the name of the property Request without having an instance inherited from it?

I need Request as string "Request" to avoid using hardcoded strings. Any ideas how to make this through reflection?

KingKerosin
  • 3,639
  • 4
  • 38
  • 77
  • 1
    "I need Request as string "Request"" Where do you need it? – weston Jul 26 '15 at 12:09
  • Does `typeof(BaseRequest<>).GetProperty("Request").Name` make sense? –  Jul 26 '15 at 12:10
  • @xtnd8 nope, it contains the hardcoded string `"Request"`! – weston Jul 26 '15 at 12:11
  • `typeof(BaseRequest<>).GetProperties().Single().Name` –  Jul 26 '15 at 12:14
  • @weston: I don't how this information of where I need it would change anything? – KingKerosin Jul 26 '15 at 12:19
  • @xtnd8: Single would only work if it will be the only property till the end of time (which can not be guaranteed) – KingKerosin Jul 26 '15 at 12:19
  • @KingKerosin I ask as often people want the name of the property as string inside the property itself. That can be achieved by [`CallerMemberNameAttribute`](https://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.callermembernameattribute(v=vs.110).aspx) – weston Jul 26 '15 at 12:25
  • 1
    @KingKerosin: I assume your type constraint should read `where TGeneric : IRequestFromResponse`, not `TRequest`? – Douglas Jul 26 '15 at 12:28

2 Answers2

6

Starting from C# 6, you should be able to use the nameof operator:

string propertyName = nameof(BaseRequest<ISomeInterface>.Request);

The generic type parameter used for BaseRequest<T> is irrelevant (as long as it meets the type constraints), since you are not instantiating any object from the type.

For C# 5 and older, you can use Cameron MacFarland's answer for retrieving property information from lambda expressions. A heavily-simplified adaptation is given below (no error-checking):

public static string GetPropertyName<TSource, TProperty>(
    Expression<Func<TSource, TProperty>> propertyLambda)
{
    var member = (MemberExpression)propertyLambda.Body;
    return member.Member.Name;
}

You can then consume it like so:

string propertyName = GetPropertyName((BaseRequest<ISomeInterface> r) => r.Request);
// or //
string propertyName = GetPropertyName<BaseRequest<ISomeInterface>, ISomeInterface>(r => r.Request);
Community
  • 1
  • 1
Douglas
  • 53,759
  • 13
  • 140
  • 188
1

Can you elaborate a little more on what it is you're trying to achieve? It looks like you're making requests to web API, for what purpose are you wanting the name of the property and in what context?

This will get you the names of all of the properties in an object type:

var properties = typeof(MyClass).GetProperties(BindingFlags.Public | BindingFlags.Static).Select(p => p.Name);
Orbittman
  • 306
  • 1
  • 6
  • I'm trying to set the `BindAttribute`s Prefix-value to the name of the property `"Request"` without using hardcoded string. See the question here: http://stackoverflow.com/questions/31616609/asp-net-mvc-4-property-renaming-for-posting – KingKerosin Jul 26 '15 at 12:27