C# 在早期版本的C中,有没有更干净的方法来编写空传播?

C# 在早期版本的C中,有没有更干净的方法来编写空传播?,c#,C#,我有这门课 class Property { public int? PropertyId { get; set; } } 我在C 6.0中写了以下语句 Property p = null; var id = p?.PropertyId.GetValueOrDefault() ?? 0; 结果证明空传播在C5.0中不起作用。我将其改写为: int id = 0; if (propertyByAddress != null && propertyByAddre

我有这门课

class Property
{
    public int? PropertyId { get; set; }
}    
我在C 6.0中写了以下语句

Property p = null;
var id = p?.PropertyId.GetValueOrDefault() ?? 0; 
结果证明空传播在C5.0中不起作用。我将其改写为:

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

这似乎是不必要的罗嗦。在C5.0中有没有更干净的方法呢?

您可以使用LINQ和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;
所以没有那么简洁,但比

以下是一些文字:


请注意,虽然大多数教程都提供了一个特殊的Maybe包装类,但您可以使用普通的null来实现;请参阅底部的我的评论:

您可以使用LINQ和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;
所以没有那么简洁,但比

以下是一些文字:

请注意,虽然大多数教程都提供了一个特殊的Maybe包装类,但您可以使用普通的null来实现;请参阅底部的我的评论:

您仍然可以在C 5.0中使用,但是您的空检查是必要的

int id = 0;
Property p = null;

if (p != null)
    id = p.PropertyId.GetValueOrDefault();
你也可以像Camilo所指出的那样做一个扩展方法,如果你觉得这样更干净的话

PropertyExtensions.cs

用法:

Property p = null;
var id = p.GetPropertyIdValueOrDefault();
var id = Property.N(p => p.PropertyId) ?? 0;
您仍然可以在C5.0中使用,但是您的空检查是必要的

int id = 0;
Property p = null;

if (p != null)
    id = p.PropertyId.GetValueOrDefault();
你也可以像Camilo所指出的那样做一个扩展方法,如果你觉得这样更干净的话

PropertyExtensions.cs

用法:

Property p = null;
var id = p.GetPropertyIdValueOrDefault();
var id = Property.N(p => p.PropertyId) ?? 0;
不如?漂亮,但这会起作用:

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);
    }
}
不如?漂亮,但这会起作用:

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);
    }
}


就我所知就是这样?。可能是我最喜欢的C 6特性:为什么要使用GetValuerDefault?p?不动产ID??0也应该是一样的。我建议使用扩展方法,但如果是word@juharr说得好。但在C5中有争议:它似乎不必要地冗长。好吧,是的,否则的话?。运算符在c6中不会被引入。就我所知,在C5中你不可能有C6简洁的优点?。可能是我最喜欢的C 6特性:为什么要使用GetValuerDefault?p?不动产ID??0也应该是一样的。我建议使用扩展方法,但如果是word@juharr说得好。但在C5中有争议:它似乎不必要地冗长。好吧,是的,否则的话?。运算符在c6中不会被引入。你不可能在C5中获得C6简洁的好处…你确定你回答了正确的问题吗?这绝对与这个问题无关question@CamiloTerevinto你知道莫纳德是什么吗?这是函数式语言中进行空传播的标准方法。这怎么和这个问题无关?我想知道是谁谈论函数式语言。。。这是一个简单的POCO,中间没有任何LINQ。此外,如果有什么区别的话,这比双重if检查要冗长得多。我同意这种方法是过分的。我不同意这种方法是离题的,或者与非函数式语言无关。空的传播不是在句点之前吗?。不是。你确定你回答了正确的问题吗?这绝对与这个问题无关question@CamiloTerevinto你知道莫纳德是什么吗?这是函数式语言中进行空传播的标准方法。这怎么和这个问题无关?我想知道是谁谈论函数式语言。。。这是一个简单的POCO,中间没有任何LINQ。此外,如果有什么区别的话,这比双重if检查要冗长得多。我同意这种方法是过分的。我不同意这种方法是离题的,或者与非函数式语言无关。空的传播不是在句点之前吗?。不