我希望能够传递任何可能的类型作为函数参数。
现在,传递属性有问题,例如
class Foo
{
public int Bar { get; set; }
}
我可以使用:(Foo.Bar)名称但我不能做A(Foo.Bar),其中A中会使用nameof。
我想确保字符串是从属性创建的,我想让属性传递给API,并在API内部进行命名。
是否有可能将属性通过函数传递到nameof?我想在类中隐藏属性到字符串的转换,而不是准备好字符串。如何做到这一点?
编辑:线索是关于:
class B
{
public Prop {get; set;}
}
void foo([?])
{
Console.WriteLine(nameof([?]));
}
是什么把[?]改为具有控制台输出,如:Prop。
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();
}
我认为您在这里对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
}