是否可以为 C# nameof 运算符编写包装器?



我读了一个关于nameof运算符的相关问题和答案,但它对我没有帮助,所以我在这里问了它。

我想为 C#nameof运算符编写一个包装器,这样它不仅会返回类属性的名称,还会将其与类名连接起来。

让我们假设一个具有单个属性的类:

class Foo
{
public string SomeProperty {get; set;}
}

现在,如果使用(C# 6 或更高版本(编译Console.WriteLine(nameof(Foo.SomeProperty)),结果将是:

一些属性

所以有可能有这样的东西:

public string PrintFullName(???? object)
{
//????
}

我为输入Type输入????,因为我不知道正确的输入Type是什么。

我希望打印全名的结果是:

福某某属性

我不一定寻找运行时解决方案。任何编译时解决方法也会有所帮助。

当然,使用表达式树这是可能的。

本网站的完整解释(所有功劳均归戴夫·格利克所有(。

归根结底是这样的:

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());
}

像这样使用它:

UseNames<Foo>(x => nameof(x.Bar));
UseNames<Foo>(x => nameof(x.Baz));

一个简单(也许更快(的解决方案,没有表达式树(使用反射(:

public string PrintFullName<T>(String memberName)
{
return $"{typeof(T).Name}.{memberName}";
}

用法:

PrintFullName<SomeType>(nameof(SomeType.SomeProperty));
// Compiled to: PrintFullName<SomeType>("SomeProperty");

nameof()是一个编译时构造,因此无需构建在运行时执行的评估超出要求的稍微高级的解决方案。

相关内容

  • 没有找到相关文章

最新更新