我希望能够将任何可能的类型作为函数参数传递。
现在,传递属性存在问题,例如。
class Foo
{
public int Bar { get; set; }
}
我可以使用: nameof(Foo.Bar) 但我无法做A(Foo.Bar)在A中将使用nameof。
我想确保字符串是从属性创建的,我希望将属性传递给API并在API中进行名称。
是否有可能通过函数将属性传递给nameof?我想隐藏属性转换为我的类内部的字符串而不是准备好字符串。如何实现?
编辑:线索是关于:
class B
{
public Prop {get; set;}
}
void foo([?])
{
Console.WriteLine(nameof([?]));
}
代替[?]使控制台输出如:Prop。
答案 0 :(得分:1)
我认为你在这里解释nameof
有点不对。
在您的第一个示例中,该方法将始终打印T
,并且不依赖于T
的类型。 nameof
关键字除了用表达式的字符串表示替换给它的表达式外什么都不做。例如我们提供nameof
参数T
,他将返回该表达式的字符串表示形式:T
。
void A<T>(T smth)
{
Console.Writeline(nameof(T)); // example usage
}
一般来说,nameof
的用法是为方法提供可重构的方法/属性/ ...名称。
例如,ArgumentOutOfRangeException
具有参数名称超出范围作为参数。
void Test(int value)
{
if (value < 0) throw new ArgumentOutOfRangeException("value");
// yada yada
}
如果我们将名称提供为上面示例中的硬编码字符串,则在重命名参数时会出现不一致。
为了解决这个问题,我们使用nameof
,因为我们提供参数本身而不是硬编码字符串,所以它是重构安全的。
void Test(int value)
{
if (value < 0) throw new ArgumentOutOfRangeException(nameof(value));
// yada yada
}
答案 1 :(得分:1)
c#编译器在编译时使用'nameof'来查找和替换事物,因此它不会像你期望的那样工作。相反,您需要使用表达式或反射在运行时获取属性的名称。 以下是使用表达式执行此操作的示例:
public static string GetName<T>(Expression<Func<T>> expression)
{
var member = (MemberExpression)expression.Body;
return member.Member.Name;
}
public static string GetName<T>(Expression<Func<T, object>> expression)
{
var body = expression.Body as MemberExpression;
if (body == null)
{
body = ((UnaryExpression)expression.Body).Operand as MemberExpression;
}
return body.Member.Name;
}
public static void PrintName<T>(Expression<Func<T>> expression)
{
Console.WriteLine(GetName(expression));
}
public static void PrintName<T>(Expression<Func<T, object>> expression)
{
Console.WriteLine(GetName(expression));
}
像这样使用:
class B
{
public Prop {get; set;}
}
static void Main(string[] args)
{
PrintName<B>((b) => b.Prop);
//Or
var someObject = new B();
PrintName(() => someObject.Prop);
Console.ReadLine();
}