迭代方法的参数以进行验证

时间:2009-10-01 12:24:55

标签: c# .net null

我一直在想能够做这样的事情是有用的,例如,检查空引用的参数并最终抛出异常。
这样可以节省一些打字,并且如果添加新参数,也会忘记添加检查。

8 个答案:

答案 0 :(得分:15)

嗯,除非算上,否则不会:

public void Foo(string x, object y, Stream z, int a)
{
    CheckNotNull(x, y, z);
    ...
}

public static void CheckNotNull(params object[] values)
{
    foreach (object x in values)
    {
        if (x == null)
        {
            throw new ArgumentNullException();
        }
    }
}

为避免数组创建命中,您可能会为不同数量的参数设置多个重载:

public static void CheckNotNull(object x, object y)
{
    if (x == null || y == null)
    {
        throw new ArgumentNullException();
    }
}

// etc

另一种方法是使用属性声明参数不应为null,并获取PostSharp以生成相应的检查:

public void Foo([NotNull] string x, [NotNull] object y, 
                [NotNull] Stream z, int a)
{
    // PostSharp would inject the code here.
}

不可否认,我可能希望PostSharp将其转换为Code Contracts个电话,但我不知道两者在一起玩得多好。也许一天,我们将能够编写Spec#-like:

public void Foo(string! x, object! y, Stream! z, int a)
{
    // Compiler would generate Code Contracts calls here
}

......但不是在不久的将来:)

答案 1 :(得分:2)

您可以使用params关键字定义方法参数。这样就可以将可变长度的参数传递给您的方法。然后,您可以迭代它们并检查空引用或任何您想要的内容。

public void MyMethod(params object[] parameters) {
     foreach (var p in parameters) {
         ...
     }
}

// method call:
this.MyMethod("foo", "bar", 123, null, new MyClass());

但是,在我看来,这不是一种好的做事方式。您必须手动控制参数的类型,它们在输入数组中的位置,并且您将无法在Visual Studio中对它们使用intellisense。

答案 2 :(得分:1)

我前段时间遇到了同样的问题,但是为了记录目的却想这样做。我从来没有找到一个好的解决方案,但是找到了关于使用基于AOP的方法来记录方法条目和退出的链接。它的要点是需要使用一个框架,它可以读取您的类并在运行时注入代码来执行您要执行的操作。听起来不容易。

How do I intercept a method call in C#?

答案 3 :(得分:0)

可以迭代已经为方法声明的参数(通过反射),但我看不到为特定方法调用检索这些参数的值...

也许您可以使用Postsharp,并在执行此检查的位置创建方面。然后,在编译时,Postsharp可以在你编写的每个方法中“编织”方面(注入额外的代码)......

答案 4 :(得分:0)

您可以查看可以作为自动验证示例的The Validation Application BlockThe Unity Application Block(特别是其拦截功能),以拦截调用和检查参数。

答案 5 :(得分:0)

您很可能会使用AOPPostSharp库自动执行参数检查。

答案 6 :(得分:0)

在使用params关键字提供方法的简单示例后,RaYell说:

  

但是,在我看来,这不是一件好事   做事的方式。你不得不   手动控制你的类型   参数,它们在的位置   输入数组,你将无法   在Visual中使用intellisense   工作室。

我当然同意声明一个方法,该方法需要两个strings,一个int,一个object可以为null,另一个MyClass对象使用{{1是个坏主意。但是,(在我看来)params关键字的完全有效和适当的应用,即当参数都是相同类型时。例如:

params

答案 7 :(得分:0)

@login_required
def rep(request):
    return render(request, 'retest/home.html', {})

您将获得空参数列表。

那么你可以添加

var mandatoryFields = (new object[] { input1, input2 }).Where(v => v == null || v.ToString().Trim() == "");