2

我在我的项目中使用了大量以不同类导出的数据库数据。例如,我有

transaction.Layout.Multimedia.Images.first();

问题是这些属性不一定可用。

所以,有可能transaction.Layout是空的,有可能transaction.Layout.Multimedia是空的,等等。

我目前对每个属性都使用它:

if (transaction.Layout != null)
{
    if (transaction.Layout.Multimedia != null)
    {
        if (transaction.Layout.Multimedia.Images != null)
        {
            if (transaction.Layout.Multimedia.Images.count > 0)
            {
                var img = transaction.Layout.Multimedia.Images.first();
            }
        }
    }
}

我想知道是否有更好的方法可以检查所有父类以确保我需要的属性可用。这些不是我使用的唯一对象,还有其他名称完全不同的对象。

提前致谢

4

3 回答 3

8

不,还没有.NET ( Roslyn )的新版本具有Null 传播运算符

然后你可以这样做:

if (transaction?.Layout?.Multimedia?.Image?.count > 0)
{
    var img = transaction.Layout.Multimedia.Images.first();
}

目前,我们坚持这一点。您可以通过连接检查来最小化所需的行,如下所示:

if ( transaction.Layout != null
     && transaction.Layout.Multimedia != null
     && transaction.Layout.Multimedia.Images != null
     && transaction.Layout.Multimedia.Images.count > 0
   )
{
    var img = transaction.Layout.Multimedia.Images.first();
}

没有什么可做的了。

于 2014-08-18T11:21:22.550 回答
2

您可以尝试使用 Maybe monad。更详细的描述在链式空检查和 Maybe monad

WithIf 扩展方法将允许您编写:

var img = transaction.With(x => x.Layout)
                     .With(x => x.Multimedia)    
                     .With(x => x.Images)
                     .If(x => x.count > 0))
                     .With(x => x.first());

With方法看起来像:

public static TResult With<TInput, TResult>(this TInput o, Func<TInput, TResult> evaluator)
  where TResult : class where TInput : class
{
  if (o == null) return null;
  return evaluator(o);
}

If方法:

public static TInput If<TInput>(this TInput o, Func<TInput, bool> evaluator) 
  where TInput : class
{
  if (o == null) return null;
  return evaluator(o) ? o : null;
}
于 2014-08-18T11:31:48.470 回答
1

这有点 OT,但理论上,您可以使用扩展方法来实现更简单的语法:

public static class GetterExtensions {
  public static LayoutClass GetLayout(this TransactionClass transaction) {
    if (transaction == null)
      return null;
    else
      return transaction.Layout;
  }
  public static MultimediaClass GetMultimedia(this LayoutClass layout) {
    if (layout == null)
       return null;
    else
       return layout.Multimedia;
  }
  public static ImagesClass GetImages(this MultimediaClass multimedia) {
    if (multimedia == null)
       return null;
    else
       return multimedia.Images;
  }
  public static int? GetCount(this ImagesClass images) {
    if (images == null)
       return null;
    else
       return images.count;
  }
}

(其中LayoutClassMultimediaClass是各个属性的类型)。

有了这个,你可以写

if (transaction.GetLayout().GetMultimedia().GetImages().GetCount() > 0)
  // ...

该解决方案利用了这样一个事实,即可以在null对象上调用扩展方法而不会引发异常。在这种情况下,他们只是将null其作为this参数。也不是方法的int?返回类型 ( Nullable<int>) GetCount(),它允许返回null整数属性。

但是,如果您有许多对象(具有许多属性),则此解决方案可能不切实际,并且需要大量额外的维护工作。此外,写GetLayout()而不是简单地写Layout仍然不那么优雅。

于 2014-08-18T11:42:22.173 回答