是否有一种简单快捷的方法来检查变量/属性值
本文关键字:方法 检查 变量 属性 简单 一种 是否 | 更新日期: 2023-09-27 18:30:07
我想知道是否有一种简单快捷的方法来检查变量/属性值是否符合某些条件?
目前,我的代码中最流行的一行与此类似:
if (string.IsNullOrWhiteSpace(someFileName))
{
throw new NullReferenceException("'someFileName' must not be null.");
}
然后异常被记录在catch部分,执行继续,依此类推
我不喜欢把这行写得到处都是,只更改变量名。如果一个人能写这样的东西就太好了:
Assert.IsNotNullOrWhiteSpace(someFileName);
它抛出了一个异常,说"{my variable}不能为null",可能还有一些额外的信息,比如父类等,如果只有可用的日志,这些信息将帮助您调试代码。
编写这样一个实用程序类时遇到的问题是,抛出的异常当然有错误的堆栈跟踪,就像它发生在实用程序方法中一样,而不是在调用断言函数的方法中。
这种值检查尤其需要在运行时进行,因为我大部分时间都会检查用户输入,如设置、路径、输入等。
编辑:
我想我应该举一个我努力实现的目标的例子:
public class FileExtractor {
public Form MainForm { get; set; }
public void ExtractFile(string fileName) {
Assert.IsNotNullOrWhiteSpace(fileName);
Assert.IsNotNull(MainForm);
// ...
}
}
让我们称之为Assert库应该这样做:
public static Assert {
public static void IsNotNullOrWhiteSpace(this string value) {
if (string.IsNullOrWhiteSpace(value)) {
// throw an exception like it occured in the ExtractFile
// the message should contain a hint like: "fileName must not be null"
}
}
public static void IsNotNull(this object value) {
if (value == null) {
// throw an excaption like it occured in the ExtractFile,
// the messagge should contain a hint like: "FileExtractor.MainForm must not be null."
}
}
EDIT-2
@CodeCaster-不幸的是,我还不能使用C#6。
在对堆叠式进行了一些研究之后,受到了另外两个问题的启发
如何在没有.Compilet()的情况下从MemberExpression中获取属性值?
和
获取变量或参数的名称
到目前为止,我想到了这个:
namespace ExceptionTest
{
class Program
{
static void Main(string[] args)
{
object test = null;
Assert.IsNotNull(() => test);
}
}
static class Assert
{
public static void IsNotNull<T>(Expression<Func<T>> expression)
{
MemberExpression memberExpr = expression.Body as MemberExpression;
var constExpr = memberExpr.Expression as ConstantExpression;
var value = (memberExpr.Member as FieldInfo).GetValue(constExpr.Value);
if (value == null)
{
throw new ArgumentNullException(memberExpr.Member.Name);
}
}
}
}
它几乎满足了我的需要。最后一件事是修改堆栈跟踪,使其指向Main
方法,而不是IsNotNull
您可以使用调试方法(http://msdn.microsoft.com/en-us/library/System.Diagnostics.Debug_methods%28v=vs.110%29.aspx),但仅在调试模式下编译时才起作用。
也许Debug.WriteLineIf(Boolean, String)
能满足您的需求?
http://msdn.microsoft.com/en-us/library/y94y4370%28v=vs.110%29.aspx
如何将属性应用于属性http://msdn.microsoft.com/en-us/library/dd901590(VS.95).aspx
我认为您应该尝试使用Fody库。对于空卫士,你可以在这里找到一个包。所有库都可以通过Nuget获得。
Fody是某种AOP库,它使用"编织"技术来操作程序集的IL并注入额外的代码。
因此NullReferenceExcpetion
(或者NullArgumentException
)将从您的方法中抛出。
GitHub示例:
您的代码
public void SomeMethod(string arg)
{
// throws ArgumentNullException if arg is null.
}
public void AnotherMethod([AllowNull] string arg)
{
// arg may be null here
}
遵守了什么
public void SomeMethod(string arg)
{
if (arg == null)
{
throw new ArgumentNullException("arg");
}
}
public void AnotherMethod(string arg)
{
}