当前位置:  开发笔记 > 编程语言 > 正文

您在c#中声明参数正确性时发现的最流畅,最吸引人的语法是什么?

如何解决《您在c#中声明参数正确性时发现的最流畅,最吸引人的语法是什么?》经验,为你挑选了6个好方法。

任何语言中的一个常见问题是断言发送到方法的参数满足您的要求,如果不满足,则发送好的,信息丰富的错误消息.这种代码反复重复,我们经常尝试为它创建帮助器.然而,在C#中,似乎那些帮助者被迫处理语言和编译器强加给我们的一些重复.为了表明我的意思,让我提供一些没有帮助的原始代码,然后是一个可能的帮助器.然后,我会指出帮助器中的重复并准确地说出我的问题.

首先,代码没有任何帮助:

public void SomeMethod(string firstName, string lastName, int age)
{
     if(firstName == null)
     {
          throw new WhateverException("The value for firstName cannot be null.");
     }

     if(lastName == null)
     {
          throw new WhateverException("The value for lastName cannot be null.");
     }

     // Same kind of code for age, making sure it is a reasonable range (< 150, for example).
     // You get the idea
}

}

现在,代码合理地尝试帮助:

public void SomeMethod(string firstName, string lastName, int age)
{
      Helper.Validate( x=> x !=null, "firstName", firstName);
      Helper.Validate( x=> x!= null, "lastName", lastName);
}

主要的问题是这样的:请注意代码如何具有传递参数的值参数("名字"的名称的firstName).这是错误消息可以说,"Blah blah blah firstName参数的值." 你有没有办法用反射或其他任何东西解决这个问题?还是一种减轻痛苦的方法?

更一般地说,您是否找到了其他方法来简化验证参数的任务,同时减少代码重复?

编辑:我读过人们谈论使用Parameters属性,但从来没有找到解决方法.谁有运气呢?

谢谢!



1> John Feminel..:

你应该查看代码合同 ; 他们几乎完全按照你的要求行事.例:

[Pure]
public static double GetDistance(Point p1, Point p2)
{
    CodeContract.RequiresAlways(p1 != null);
    CodeContract.RequiresAlways(p2 != null); 
    // ...
}



2> Charlie Flow..:

哇,我在这里找到了一些非常有趣的东西.Chris上面给出了另一个Stack Overflow问题的链接.其中一个答案指向一篇博文,其中描述了如何获取这样的代码:

public static void Copy(T[] dst, long dstOffset, T[] src, long srcOffset, long length)
{
    Validate.Begin()
            .IsNotNull(dst, “dst”)
            .IsNotNull(src, “src”)
            .Check()
            .IsPositive(length)
            .IsIndexInRange(dst, dstOffset, “dstOffset”)
            .IsIndexInRange(dst, dstOffset + length, “dstOffset + length”)
            .IsIndexInRange(src, srcOffset, “srcOffset”)
            .IsIndexInRange(src, srcOffset + length, “srcOffset + length”)
            .Check();

    for (int di = dstOffset; di < dstOffset + length; ++di)
        dst[di] = src[di - dstOffset + srcOffset];
}

我不相信这是最好的答案,但可以肯定的是有趣的.这是来自Rick Brewster 的博客文章.



3> Daniel Earwi..:

几周前我解决了这个确切的问题,因为我认为测试库似乎需要一百万个不同的版本Assert才能使他们的消息具有描述性,这很奇怪.

这是我的解决方案.

简要总结 - 给出这段代码:

int x = 3;
string t = "hi";
Assert(() => 5*x + (2 / t.Length) < 99);

我的Assert函数可以打印出传递给它的内容的以下摘要:

(((5 * x) + (2 / t.Length)) < 99) == True where
{
  ((5 * x) + (2 / t.Length)) == 16 where
  {
    (5 * x) == 15 where
    {
      x == 3
    }
    (2 / t.Length) == 1 where
    {
      t.Length == 2 where
      {
        t == "hi"
      }
    }
  }
}

因此,所有标识符名称和值以及表达式的结构都可以包含在异常消息中,而无需在引用的字符串中重述它们.



4> core..:

这可能有点帮助:

按契约/ C#4.0设计/避免ArgumentNullException



5> Charlie Flow..:

好吧,伙计们,这又是我,我找到了令人惊讶和令人愉快的其他东西.这是另一个博客文章,上面提到的克里斯提到的其他SO问题.

这个人的方法让你写这个:

public class WebServer
    {
        public void BootstrapServer( int port, string rootDirectory, string serverName )
        {
            Guard.IsNotNull( () => rootDirectory );
            Guard.IsNotNull( () => serverName );

            // Bootstrap the server
        }
    }

请注意,没有包含"rootDirectory"的字符串,也没有包含"serverName"的字符串!! 然而他的错误消息可以说"rootDirectory参数不能为空".

这正是我想要的,超出了我的期望.这是该家伙博客文章的链接.

实现非常简单,如下所示:

public static class Guard
    {
        public static void IsNotNull(Expression> expr)
        {
            // expression value != default of T
            if (!expr.Compile()().Equals(default(T)))
                return;

            var param = (MemberExpression) expr.Body;
            throw new ArgumentNullException(param.Member.Name);
        }
    }

请注意,这会使用"静态反射",因此在紧密循环或其他情况下,您可能希望使用上面的Rick Brewster方法.

我发布这篇文章后,我会立即投票给Chris,以及对另一个SO问题的回应.这是一些好东西!!!



6> Kent Boogaar..:

使用我的图书馆The Helper Trinity:

public void SomeMethod(string firstName, string lastName, int age)
{
    firstName.AssertNotNull("firstName");
    lastName.AssertNotNull("lastName");

    ...
}

还支持断言枚举参数是正确的,集合及其内容是非的null,字符串参数是非空的等等.有关详细示例,请参阅此处的用户文档.

推荐阅读
殉情放开那只小兔子
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有