在早期版本的C#中是否有更简洁的方法来编写空传播?

时间:2017-08-14 17:44:07

标签: c#

我有这门课。

class Property
{
    public int? PropertyId { get; set; }
}    

我在C#6.0中写了以下声明

Property p = null;
var id = p?.PropertyId.GetValueOrDefault() ?? 0; 

结果是空传播在C#5.0中不起作用。我把它重写为:

int id = 0;
if (propertyByAddress != null && propertyByAddress.PropertyId != null)
{
    id = p.PropertyId.Value;
}

似乎不必要的罗嗦。在C#5.0中有更简洁的方法吗?

3 个答案:

答案 0 :(得分:2)

你仍然可以在C#5.0中使用GetValueOrDefault,但是你的空检查是必要的。

int id = 0;
Property p = null;

if (p != null)
    id = p.PropertyId.GetValueOrDefault();

如果您觉得“更清洁”,您也可以按照Camilo的指示制作扩展方法。

<强> PropertyExtensions.cs

public static int GetPropertyIdValueOrDefault(this Property p)
{
    if (p != null)
        return p.PropertyId.GetValueOrDefault();

    return 0;
}

用法:

Property p = null;
var id = p.GetPropertyIdValueOrDefault();

答案 1 :(得分:1)

您可以使用LINQ和Maybe monad。这将允许你写例如。

var supSupNameOpt =
  from employee in employeeOpt
  from supervisor in employee.ReportsTo
  from supervisorSupervisor in supervisor.ReportsTo
  select supervisorSupervisor.Name;

这相当于

var supSupNameOpt = employeeOpt?.ReportsTo?.ReportsTo?.Name;

所以不像?.那么简洁,但比pyramid of doom更漂亮。

以下是一些写作:https://codewithstyle.info/understand-monads-linq/ https://ericlippert.com/2013/04/02/monads-part-twelve/

请注意,虽然大多数教程为此提供了一个特殊的Maybe<T>包装类,但您可以使用普通的旧空值来实现;请在底部查看我的评论:https://smellegantcode.wordpress.com/2008/12/11/the-maybe-monad-in-c/

答案 2 :(得分:1)

不像GlideApp那么漂亮,但这可行:

?.

用法:

public static class ObjectExtensions
{
    public static Tout N<Tin, Tout>(this Tin val, Func<Tin, Tout> e)
    {
        if (val == null)
            return default(Tout);

        return e(val);
    }
}