为方法及其调用方创建简单的IsNullOrFalse方法

时间:2011-08-29 15:57:17

标签: c#

我发现自己做了很多。

if( obj == null || !obj.SomeMethodThatReturnsABoolean() ) {
  // then do this
}

我的意思是,我只是看到它在许多地方混乱了代码。这不是一件坏事,但如果你不能把它洒在这里和那里使它变得更苗条的话,那么语法糖的乐趣是什么?

所以我试着制作一个非常简陋的小方法,IsNullOrFalse。这个想法是它将测试传入的内容,看它是否为null,如果没有,它将运行该方法,并返回布尔结果。

实际证明这比我想象的要困难得多。在任何项目中我都不需要继续这样做,但此时我已经从好奇变为好奇。

还有其他人做过这样的事吗?我得到的问题是我无法传递包含方法的不存在的东西。

4 个答案:

答案 0 :(得分:5)

这是一个可以实现技巧的扩展方法

public static bool IsNullOrFalse<T>(this T value, Func<T, bool> del) 
  where T : class { 
  return value == null || !del(value);
}

现在你可以写

if (obj.IsNullOrFalse(o => o.SomeMethodThatReturnsABoolean())) {
  ...
}

注意:我个人不会采取这种做法,而是更喜欢长手。这种解决方案会产生额外的分配(封闭+委托),一般来说并不比原来的短。

此外,我一直在看到一个对null值进行操作的扩展方法。虽然在C#中完全合法,但它确实使得调用站点代码难以遵循,因为开发人员不知道API是一种扩展方法。

答案 1 :(得分:0)

如果真的想要你可以使用检查null的方法并执行谓词,如果不是null:

public bool IsNullOrFalse(object obj, Func<bool> predicate)
{
    if (obj == null)
        return true;

    else return !predicate();
}

答案 2 :(得分:0)

@ JaredPar答案的稍微更通用的版本:

    public static TResult ValueOrDefaultIfNull<T, TResult>(this T obj, Func<T, TResult> getter, TResult defaultValue = default(TResult)) where T : class
    {
        return obj != null ? getter(obj) : defaultValue;
    }

用法:

        if (!obj.ValueOrDefaultIfNull(mc => mc.SomeMethodThatReturnsABoolean()))
        {

        }

这可以返回任何类型的返回,而不仅仅是bool,所以例如你可以做类似的事情:

string zipCode = contact
    .ValueOrDefaultIfNull(c=>c.Address)
    .ValueOrDefaultIfNull(a=>a.ZipCode, string.Empty);

答案 3 :(得分:0)

以下是您问题的另一种解决方案。您可以创建一个对象的标准Empty实例(如String.Empty,DateTime.MinValue等),当调用SomeMethodThatReturnsABoolean()时,它将返回false。 然后您的调用者代码将如下所示:

if ((obj ?? objEmpty).SomeMethodThatReturnsABoolean()){ 
    // then do this
}

??当obj为null时,operator将使用objEmpty实例,而当为objEmpty调用时,objEmpty.SomeMethodThatReturnsABoolean()将返回false。

但是,在SomeMethodThatReturnsABoolean()方法中可能需要一些努力:

private bool isEmptyInstance;    
public bool SomeMethodThatReturnsABoolean()
{
  if (isEmptyInstance) { return false; }

  // rest of the method
}