获取泛型抽象类的属性名称

3

考虑以下一般抽象类的实现:

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

是否有可能在没有从中继承实例的情况下获得属性Request的名称?

我需要将Request作为字符串"Request",以避免使用硬编码的字符串。有什么想法可以通过反射来实现这一点吗?


1
我需要将请求作为字符串“Request”。您需要在哪里使用它? - weston
@xtnd8 不对,它包含了硬编码的字符串 "Request"! - weston
@weston:我不知道我需要这个信息会改变什么? - KingKerosin
@xtnd8:只有在到最后它将是唯一的属性(这是无法保证的)时,Single 才能起作用。 - KingKerosin
1
@KingKerosin:我猜你的类型约束应该写成where TGeneric : IRequestFromResponse,而不是TRequest - Douglas
显示剩余3条评论
2个回答

6

从C# 6开始,您应该能够使用nameof运算符:

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

BaseRequest<T>中使用的泛型类型参数并不重要(只要符合类型约束),因为您不会从该类型实例化任何对象。

对于C#5及更早版本,您可以使用Cameron MacFarland的答案来从lambda表达式中检索属性信息。以下是一个大大简化的适配器示例(没有错误检查):

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

您可以像这样使用它:
string propertyName = GetPropertyName((BaseRequest<ISomeInterface> r) => r.Request);
// or //
string propertyName = GetPropertyName<BaseRequest<ISomeInterface>, ISomeInterface>(r => r.Request);

我有一个通用的约束条件,即 TGeneric 必须继承 ISomeInterface,因此对象在此处不允许。 - KingKerosin
@KingKerosin:在这种情况下,使用BaseRequest<ISomeInterface>而不是BaseRequest<object>,上述代码应该可以工作。再次强调,ISomeInterface是接口或抽象类并不重要。 - Douglas
在使用C# 5时,nameof不是一个选项(至少对我来说不是)。 - KingKerosin
可以理解;C# 6只发布了6天。我只是想让我的回答具备未来性。 - Douglas
你的回答对我来说非常棒。谢谢。 - muratoner

1
请您详细说明一下您想实现什么功能?看起来您正在向Web API发送请求,您需要获取属性名称的目的是什么?在什么情况下需要这些属性名称?
以下代码将获取对象类型中所有属性的名称:
var properties = typeof(MyClass).GetProperties(BindingFlags.Public | BindingFlags.Static).Select(p => p.Name);

我正在尝试将 BindAttribute 的前缀值设置为属性名称 "Request",而不使用硬编码字符串。请参阅此处的问题:http://stackoverflow.com/questions/31616609/asp-net-mvc-4-property-renaming-for-posting - KingKerosin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接