使用属性检查空参数

时间:2014-04-10 13:38:37

标签: c#

是否可以使用属性本机检查参数的值?我已经看到像[FromUri]这样的系统属性。我希望有这样的事情:

public void Method([NotNull] string name, [NotNull] DateTime? date)
{  }

其中NotNull是一个检查值以查看它是否为null的属性。如果该值为null,则会引发错误。

以下是我目前的内容

我目前正在使用一个静态助手类,它接受一个表达式和参数本身来确定该值是否为null并使用该表达式来确定参数的名称。

// Invoke method within ArgumentHelper class
ArgumentHelper.RequireNotNullOrEmpty(() => state, state);

// Method within static class ArgumentHelper
public static void RequireNotNullOrEmpty<T>(this Expression<Func<T>> argumentExpression, string value)
    {
        var body = ((MemberExpression)argumentExpression.Body);
        if (string.IsNullOrEmpty(value))
        {
            // Throw error "Required field '" + body.Member.Name + "' is missing.";
        }
    }

奖金:如果我能以某种方式获取变量的名称而不传递带有名称的字符串,就像我当前的解决方案一样,这也很好。

2 个答案:

答案 0 :(得分:3)

绝对不是最高效的,但你走在正确的轨道上。这是一个包装器,它可以完成PostSharp在IL中所做的一些工作。这仅适用于传递对象,它在将另一个方法作为参数传递时会发生故障。但是,解决这个问题只是一点点工作。

在生产中我会扩展它以构建一个委托的反射,我可以缓存以供以后使用。

public class SomeClass
{
    public void Method([NotNull] string Param1, [NotNull] string Param2)
    { }
}

public static class SomeClassExtensions
{
    public static void InvokeWithNullCheck<TObject>(this TObject obj, Expression<Action<TObject>> expression)
    {
        var body = (MethodCallExpression)expression.Body;

        foreach(var parameter in body.Method.GetParameters())
        {
            bool hasNotNullAttribute = parameter.CustomAttributes.Any(x => x.AttributeType.Equals(typeof(NotNullAttribute)));
            if(hasNotNullAttribute && ((ConstantExpression)body.Arguments[parameter.Position]).Value == null)
            {
                throw new ArgumentException(String.Format("Mandatory parameter {0} was not supplied.", parameter.Name));
            }
        }

        expression.Compile()(obj);
    }
}

[TestFixture]
public class SomeClassTests
{
    [Test]
    public void Test()
    {
        var test = new SomeClass();
        Assert.Throws<ArgumentException>(() => test.InvokeWithNullCheck(x => x.Method(null, "Test")));
    }
}

答案 1 :(得分:2)

看看PostSharp(参见:http://www.postsharp.net)。它提供了许多属性,例如您正在寻找的属性。

PostSharp是一个预编译器,它将在代码中查找属性并生成适当的代码,如参数验证。