【发布时间】:2010-12-02 23:37:08
【问题描述】:
我一直认为能够做这样的事情会很有用,例如,检查参数是否有空引用并最终抛出异常。
这样可以节省一些输入,并且不会忘记添加检查是否添加了新参数。
【问题讨论】:
我一直认为能够做这样的事情会很有用,例如,检查参数是否有空引用并最终抛出异常。
这样可以节省一些输入,并且不会忘记添加检查是否添加了新参数。
【问题讨论】:
可以迭代已为方法声明的参数(通过反射),但我认为无法为特定方法调用检索这些参数的值...
也许您可以使用Postsharp,并在执行此检查的位置创建一个切面。然后,在编译时,Postsharp 可以在您编写的每个方法中“编织”方面(注入额外的代码)......
【讨论】:
您可以查看The Validation Application Block,它可以被视为自动验证的示例,而The Unity Application Block(尤其是它的拦截功能)在拦截调用和检查参数方面。
【讨论】:
好吧,除非你数数:
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
另一种方法是使用属性来声明参数不应为空,并获取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#的东西:
public void Foo(string! x, object! y, Stream! z, int a)
{
// Compiler would generate Code Contracts calls here
}
...但不会在不久的将来:)
【讨论】:
您可以使用params 关键字定义方法参数。这样就可以将可变长度的参数传递给您的方法。然后你可以遍历它们并检查空引用或任何你想要的。
public void MyMethod(params object[] parameters) {
foreach (var p in parameters) {
...
}
}
// method call:
this.MyMethod("foo", "bar", 123, null, new MyClass());
然而,在我看来,这不是一个好的做事方式。您将不得不手动控制参数的类型、它们在输入数组中的位置,并且您将无法在 Visual Studio 中为它们使用智能感知。
【讨论】:
前段时间我也有同样的问题,但出于记录目的想这样做。我从来没有找到一个好的解决方案,但发现这个链接是关于使用基于 AOP 的方法来记录方法进入和退出的。它的要点是需要使用一个可以读取您的类并在运行时注入代码的框架来完成您想要做的事情。听起来并不容易。
【讨论】:
在提供了一个使用 params 关键字的简单方法示例后,RaYell 说:
不过,在我看来,这不是一件好事 做事的方式。你不得不 手动控制您的类型 参数,它们在 输入数组,你将无法 在 Visual 中为他们使用智能感知 工作室。
我当然同意声明一个方法需要两个strings,一个int,一个可以为空的object,另一个使用params 的MyClass 对象是个坏主意。但是,有(在我看来)params 关键字的完全有效和适当的应用,即当参数都是相同类型时。例如:
public T Max<T>(T x, T y) where T : IComparable<T> {
return x.CompareTo(y) > 0 ? x : y;
}
public T Max<T>(params T[] values) where T : IComparable<T> {
T maxValue = values[0];
for (int i = 1; i < values.Length; i++) {
maxValue = Max<T>(maxValue, values[i]);
}
return maxValue;
}
【讨论】:
var mandatoryFields = (new object[] { input1, input2 }).Where(v => v == null || v.ToString().Trim() == "");
您将获得空参数列表。
那么你可以添加
if(mandatoryFields.ToArray().Count > 0){}
【讨论】: