是否可以使用属性在 native 检查参数值?我已经看到像 [FromUri] 这样的一些系统属性是这样使用的。我希望是这样的:
public void Method([NotNull] string name, [NotNull] DateTime? date)
{ }
其中 NotNull 是一个属性,用于检查值是否为空。如果该值为 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.";
}
}
奖励:如果我能以某种方式获取变量的名称而不传递带有变量名称的字符串,就像我当前的解决方案一样,那也很好。
最佳答案
绝对不是最高效的,但您走在正确的轨道上。这是一个包装器,它做了一些 PostSharp 在 IL 中会做的事情。这仅适用于传递对象,当将另一个方法作为参数传递时,它会按原样分解。但是,解决该问题只是需要多做一些工作。
在生产中,我会扩展它以将反射构建到一个我可以缓存以备后用的委托(delegate)中。
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")));
}
}
关于c# - 使用属性检查空参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22989696/