在许多情况下,需要表达式,参数,语句等的名称。例如:
public abstract void Log(string methodName, string parameterName, string message);
public void FooMethod(string value)
{
if (value == null)
{
this.Log("FooMethod", "value", "The value must be whatever...");
throw new ArgumentNullException("value");
}
if (value.Length < 5)
{
this.Log("FooMethod", "value.Length", "The value length must be whatever...");
throw new ArgumentException("value");
}
}
是否有任何方法可以自动获取这些字符串文字,例如使用可以像typeof(string)
一样使用的关键字?
或者是基于反射的简单而高效的方法吗?
我不是在寻找一种方法来检查和记录这个参数(这实际上只是一个例子)。我正在寻找一种方法来获取部分代码string
。
以下内容会更准确,可以由编译器检查,并在重构代码时也会考虑:
public void FooMethod(string value)
{
if (value == null)
{
this.Log(literal(this.FooMethod), literal(value), "The parameter '" + literal(value) + "' must be whatever...");
throw new ArgumentNullException(literal(value));
}
if (value.Length < 5)
{
this.Log(literal(this.FooMethod), literal(value.Length), "The value length must be whatever...");
throw new ArgumentException(literal(value));
}
}
答案 0 :(得分:2)
您可以为所有可能的类型创建这样的静态方法。以下是方法名称。
public static string GetString(Action obj)
{
return obj.Method.Name;
}
public static string GetString(Delegate obj )
{
return obj.Method.Name;
}
答案 1 :(得分:1)
听起来你需要StackTrace.GetFrame。此方法将为您提供所需的StackFrame对象,您可以从中找到此信息。
查看以下代码示例
StackFrame fr = new StackFrame(1,true);
StackTrace st = new StackTrace(fr);
this.Log.WriteEntry(fr.GetMethod().Name,
fr.GetMethod().GetParameters()[0].Name,
"The value must be whatever...");
顺便说一下,在你的第二个代码示例中,Log方法调用永远不会执行,因为在调用之前会抛出异常。除了finally
块中的代码之外,抛出异常后,方法中的代码不会执行。请参阅this article。
答案 2 :(得分:0)
这取决于你的目标是什么。如果您希望获得运行时值Martin Doms,则可能是解决方案。如果您希望能够将ArgumentNullException链接到特定的参数名称,并确保如果更改名称可以使用重构,则可以执行以下操作:
public static void NotNull<T>(Expression<Func<IEnumerable<T>>> exp)
{
var expBody = exp.Body as MemberExpression;
T value = exp.Compile().Invoke();
if (value == null){
string memberName;
if (expBody != null){
memberName = expBody.Member.Name;
} else{
memberName = "member";
}
throw new ArgumentNullException(memberName, memberName + " cannot be null");
}
}
然后您可以像这样使用它:
public void Method(string value){
Ensure.NotNull(()=>value);
}
如果value为null,它将检查该值是否为null并将适当的消息格式化为ArgumentNullException。 如果你使用的是.NET 4.0,我建议使用这些东西的合同。并不是说它实际上解决了你的特殊需求,但使用Contracts进行参数检查在文档和静态分析方面有很多好处,而不是“老式的方式”