是否可以重构此扩展方法?

Pur*_*ome 27 .net extension-methods

我有以下扩展方法:

public static void ThrowIfArgumentIsNull<T>(this T value, string argument) 
    where T : class
{
    if (value == null)
    {
        throw new ArgumentNullException(argument);
    }
}
Run Code Online (Sandbox Code Playgroud)

这是它的用法的一个例子....

// Note: I've poorly named the argument, on purpose, for this question.
public void Save(Category qwerty)
{
    qwerty.ThrowIfArgumentIsNull("qwerty");
    ....
}
Run Code Online (Sandbox Code Playgroud)

工作100%罚款.

但是,我不喜欢我必须提供变量的名称,只是为了帮助我的异常消息.

我想知道是否有可能重构扩展方法,所以可以像这样调用它...

qwerty.ThrowIfArgumentIsNull();
Run Code Online (Sandbox Code Playgroud)

它会自动确定变量的名称是'qwerty',因此将其用作ArgumentNullException的值.

可能?我假设反思可以做到这一点?

Jon*_*eet 34

不,你不能这样做.这会很好,但如果没有某种AOP参与,这是不可能的.我确信PostSharp可以做得很好,希望使用属性,而在Code Contracts中它只是:

Contract.Requires(qwerty != null);
Run Code Online (Sandbox Code Playgroud)

理想情况下,我想要一个生成Code Contracts调用的PostSharp属性 - 我会在某个时候使用它 - 但在那之前,你得到的扩展方法是我发现的最佳方法......

(如果我尝试使用PostSharp + Code Contracts方法,我肯定会在博客上发表文章,顺便说一句...... Mono Cecil也可能会让它变得相当简单.)

编辑:要扩展Laurent的答案,您可能会:

new { qwerty }.CheckNotNull();
Run Code Online (Sandbox Code Playgroud)

如果你有很多不可为空的参数,你可以:

new { qwerty, uiop, asdfg }.CheckNotNull();
Run Code Online (Sandbox Code Playgroud)

这将不得不使用反射来计算属性.有些方法可以避免对每个访问进行反射,为每个属性构建一个委托,并且通常会使其变得眩目.我可能会对博客文章进行调查...但它有点icky,我更喜欢能够将参数归因于...

编辑:代码实施,博客文章正式制作.伙计,但很有趣

  • 我读了你的博客文章,老实说,你不必经历所有那些喧嚣.只需实现一个没有params的`ThrowIfNull()`方法,让堆栈跟踪的开发人员稍稍向上移动堆栈,找出哪个参数为null.只是一个想法 :) (4认同)