如何获取在c#中作为参数传递的表达式的字符串表示形式?
我有一个用于检查参数的静态方法如何获取在c#中作为参数传递的表达式的字符串表示形式?,c#,C#,我有一个用于检查参数的静态方法 require(myStringVariable); 如果该值不符合某些要求,我只想显示一条消息 是否可以显示作为参数传递的变量(或表达式)的名称?在C++中,一个带有Srimige运算符的宏将完成这项工作。 更新:我没有搜索类似于nameof(myStringVariable)的内容。实际上,我想调用这个方法,如下所示: require(bareFname + ".ext"); 如果表达式不能通过检查,那么我将在方法内部执行如下操作 static void
require(myStringVariable);
如果该值不符合某些要求,我只想显示一条消息
是否可以显示作为参数传递的变量(或表达式)的名称?在C++中,一个带有Srimige运算符的宏将完成这项工作。
更新:我没有搜索类似于nameof(myStringVariable)
的内容。实际上,我想调用这个方法,如下所示:
require(bareFname + ".ext");
如果表达式不能通过检查,那么我将在方法内部执行如下操作
static void required(... theExpressionArgument)
{
string value = evaluate theExpressionArgument;
if (value.Length == 0)
{
Console.WriteLine("ERROR: Non empty value is required for the expression "
+ theExpressionArgument);
}
}
基于,您可以这样重写您的方法:
public static void RequireNotEmpty(Expression<Func<string>> lambda)
{
// Get the passed strings value:
string value = lambda.Compile().Invoke();
// Run the check(s) on the value here:
if (value.Length == 0)
{
// Get the name of the passed string:
string parameterName = ((MemberExpression) lambda.Body).Member.Name;
Console.WriteLine($"ERROR: Non empty value is required for the expression '{parameterName}'.");
}
}
string emptyString = "";
RequireNotEmpty(() => emptyString);
public string DoStuff(Foo fooObj, string bar)
{
Checker.RequireNotNull(() => fooObj);
Checker.RequireNotEmpty(() => bar);
// Now that you checked the preconditions, continue with the actual logic.
...
}
写
错误:表达式“emptyString”需要非空值
注意,上面的代码假设您只想检查字符串。如果不是这样,您可以使用签名
publicstaticvoidrequirenotetry(表达式lambda)
,它将适用于任何类型T
此外,我还将该方法重命名为更具可读性和意义的方法
编辑:推荐 读了你的评论后,我想这可能是你想要的:
public static class Checker
{
private static T GetValue<T>(Expression<Func<T>> lambda)
{
return lambda.Compile().Invoke();
}
private static string GetParameterName<T>(Expression<Func<T>> lambda)
{
return ((MemberExpression) lambda.Body).Member.Name;
}
private static void OnViolation(string message)
{
// Throw an exception, write to a log or the console etc...
Console.WriteLine(message);
}
// Here come the "check"'s and "require"'s as specified in the guideline documents, e.g.
public static void RequireNotEmpty(Expression<Func<string>> lambda)
{
if(GetValue(lambda).Length == 0)
{
OnViolation($"Non empty value is required for '{GetParameterName(lambda)}'.");
}
}
public static void RequireNotNull<T>(Expression<Func<T>> lambda) where T : class
{
if(GetValue(lambda) == null)
{
OnViolation($"Non null value is required for '{GetParameterName(lambda)}'.");
}
}
...
}
现在,当您使用无效参数调用DoStuff
时,例如
DoStuff(new Foo(), "");
信息
“bar”需要非空值
您的意思是
nameof(variable)
?可能的重复我认为他不想要nameof
,因为,如果他使用上述示例,但在require
中,参数被称为静态无效要求(字符串myStr)
它将输出myStr
,myStringVariable.
@SebastianHofmann:没有。我已经更新了问题来解释我需要什么。@BrootsWaymb:对不起,但我不认为它是重复的。至少,我看不出有什么相似之处。也许在C#中不可能做这样的事情。我明白了。总之,将字符串形式的表达式放入方法中的唯一方法是使其成为未编译的lambda表达式体。然后——在方法体内部——我可以编译传递的表示并调用它来获取值。同样,我仍然可以访问字符串表示。(在MemberExpression
之前缺少一个开括号)是否有更好的方法将lambda.Body
转换为外部写入的字符串?考虑编写requirenoty(()=>myEmptyVariable+”)
@pepr是唯一的方法-有一种方法不使用昂贵的表达式,而是传递一个Func
,但它依赖于IL解析,该解析只适用于简单引用(请参阅中的Reflect.cs文件)。我不确定您为什么要向字符串变量添加内容,但我很乐意进一步帮助您。你能告诉我更多你想要达到的目标吗?另外,谢谢你接受的答案,也谢谢你提到打字错误,我刚刚把它修好了。这个解决方案非常适合我。我只想传递一个变量。我只是好奇什么是可能的,什么不是。谢谢@pepr我不知道指南文件中说明了什么,但我编辑了我的答案,并添加了一个设计,我建议您进行检查和要求
。大致按照这种设计,您可以轻松创建可重用的参数检查。我希望我理解正确,这就是你想要实现的。这很好。谢谢。:)尽管如此,C#没有类似C++的宏仍然是一件微不足道的事情