[英]Is it possible to write a wrapper for the C# nameof operator?
I read a related question and answer about the nameof
operator, but it didn't help me, so I asked it here.我阅读了有关
nameof
运算符的相关问答,但它对我没有帮助,所以我在这里问了。
I want to write a wrapper for the C# nameof
operator so not only will it will return the name of a class property, but also concatenate it with the class name.我想为 C#
nameof
运算符编写一个包装器,这样它不仅会返回 class 属性的名称,而且还会将它与 class 名称连接起来。
Let's assume a class with single property:让我们假设一个具有单一属性的 class:
class Foo
{
public string SomeProperty {get; set;}
}
Now if compiling Console.WriteLine(nameof(Foo.SomeProperty))
with (C# 6 or higher) , the result will be:现在如果用(C# 6 or higher)编译
Console.WriteLine(nameof(Foo.SomeProperty))
,结果将是:
SomeProperty
一些财产
So that is it possible to have something like this:所以有可能有这样的东西:
public string PrintFullName(???? object)
{
//????
}
I put ????
我放了
????
for the input Type
, because I don't know what the proper input Type
is.对于输入
Type
,因为我不知道正确的输入Type
是什么。
I want the result of the PrintFullName to be:我希望 PrintFullName 的结果是:
Foo.SomeProperty
Foo.SomeProperty
I don't necessarily look for run -time solutions.我不一定要寻找运行时解决方案。 Any compile -time workaround will also help.
任何编译时解决方法也将有所帮助。
Sure this is possible, using expression trees.当然这是可能的,使用表达式树。
A full explanation on this site (all credits to Dave Glick).本网站上的完整说明(所有归功于 Dave Glick)。
It comes down to this:归结为:
public void UseNames(string className, string memberName)
{
// Your code to use the class & membername go here
}
public void UseNames<T>(Expression<Func<T, object>> expression)
{
MemberExpression member = expression.Body as MemberExpression;
if (member == null)
{
// The property access might be getting converted to object to match the func
// If so, get the operand and see if that's a member expression
member = (expression.Body as UnaryExpression)?.Operand as MemberExpression;
}
if (member == null)
{
throw new ArgumentException("Action must be a member expression.");
}
// Pass the names on to the string-based UseNames method
UseNames(typeof(T).Name, member.Member.Name);
}
public void UseNames<T>(Expression<Func<T, string>> expression)
{
ConstantExpression constant = expression.Body as ConstantExpression;
if (constant == null)
{
throw new ArgumentException("Expression must be a constant expression.");
}
UseNames(typeof(T).Name, constant.Value.ToString());
}
Use it like this:像这样使用它:
UseNames<Foo>(x => nameof(x.Bar));
UseNames<Foo>(x => nameof(x.Baz));
A simple (and maybe faster) solution, without expression trees (which use reflection):一个简单(也许更快)的解决方案,没有表达式树(使用反射):
public string PrintFullName<T>(String memberName)
{
return $"{typeof(T).Name}.{memberName}";
}
Usage:用法:
PrintFullName<SomeType>(nameof(SomeType.SomeProperty));
// Compiled to: PrintFullName<SomeType>("SomeProperty");
nameof()
is a compile-time construct, so no need to build a slightly advanced solution that performs evaluation at runtime more than required. nameof()
是一个编译时构造,因此无需构建一个稍微高级的解决方案,在运行时执行超出所需的评估。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.