我有下面的方法,我想检查是否有任何参数为null。如果any为null,我希望能够打印一个错误,上面写着:“'name'缺失”并显示正确的变量。
public void Method(string name, DateTime? date)
{ }
我需要能够使用自己的自定义错误处理,因此没有像ArgumentNullException那样内置。我知道可以使用if语句,但我希望使用某种验证器。有没有办法做到这一点,以便它可以跨多个方法使用,并在消息中返回正确的变量名称?
答案 0 :(得分:1)
Aspect oriented programming是以通用方式处理此类要求的常用方法。您可能需要查看PostSharp,Castle DynamicProxy或Microsoft's Unity,还有其他几种选择。但这是一个巨大的锤子,在使用它之前要仔细考虑。
对于您的特定问题,编译时编织就足够了,不需要更改代码或至多添加一些属性,但它需要更改构建过程。运行时编织不会影响您的构建过程,但可能需要进行大量的代码更改。
PostSharp Ultimate包含the aspect you want,至少差不多,或者您可以单独购买,也可以与免费版一起使用。但要自己实现它并不难。
答案 1 :(得分:1)
我不知道这是否是您所寻求的,但您是否听说过按合同设计?
Check the official code contracts' article on MSDN.
代码合同的一个可能用例是参数验证。
例如,您的代码如下所示:
public void Method(string name, DateTime? date)
{
Contract.Requires(!string.isNullOrEmpty(name), "'name' cannot be null");
Contract.Requires(date.HasValue, "'date' is required");
}
您还可以收听合同例外using a global contract handler。
如果你进一步研究代码契约,你会发现你可以创建接口和抽象类的契约,这样任何实现都会将契约注入其中。
答案 2 :(得分:1)
据我所知,你正在寻找这样的东西。
控制台输出:
方法:测试,参数:a具有空值
假
方法:测试,参数:b具有空值
假
真
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
namespace ConsoleApplication3
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine(test("", "Something").ToString());
Console.WriteLine(test("something", null, "blah").ToString());
Console.WriteLine(test("something", "blah", "blah").ToString());
Console.ReadLine();
}
public static bool test(string a, string b)
{
if (Validator.isNullOrEmpty(MethodBase.GetCurrentMethod(), a, b))
return false;
return true;
}
public static bool test(string a, string b, string c)
{
if (Validator.isNullOrEmpty(MethodBase.GetCurrentMethod(), a, b, c))
return false;
return true;
}
}
class Validator
{
public static bool isNullOrEmpty(MethodBase method, params object[] values)
{
ParameterInfo[] pars = method.GetParameters();
bool ret = false;
for(var i = 0; i < pars.Length; i++)
{
ParameterInfo p = pars[i];
string type = p.ParameterType.ToString().ToLower();
try
{
switch (type)
{
case "system.string":
ret = String.IsNullOrEmpty((string)values[i]);
break;
case "system.int32":
case "system.double":
default:
ret = values[i] != null;
break;
}
}
catch (Exception ex)
{
Console.WriteLine(String.Format("Method: {0}, Parameter: {1} has an incorrect value for a {2} with '{3}'",
method.Name, p.Name, type, values[i]));
Console.WriteLine(ex.Message);
return true;
}
if (ret)
{
Console.WriteLine(String.Format("Method: {0}, Parameter: {1} has a null value", method.Name, p.Name));
return ret;
}
}
return ret;
}
}
}
答案 3 :(得分:0)
对于字符串:
if(string.IsNullOrEmpty(name))
可以为空:
if(date.HasValue)
答案 4 :(得分:0)
public void Method(string name, DateTime? date)
{
if( name == null ){ } // you may want: if( string.IsNullOrEmpty( name ) ){}
if( date.HasValue ){ }
}
答案 5 :(得分:0)
这是我采用的解决方案,以避免安装任何新产品和学习新技术。 @Daniel有一些很好的建议可能会对这个问题起到最好的作用,但是按照这篇文章中的步骤,我能够以与我希望的方式类似的方式使它工作。
http://weblogs.asp.net/fredriknormen/archive/2008/05/08/how-to-validate-a-method-s-arguments.aspx
此外,这是另一个有趣的解决方案,虽然它需要来自微软Unity的拦截器:
http://www.codinginstinct.com/2008/05/argument-validation-using-attributes.html