在我看来,任何Option
暴露HasValue
属性的实现都是整个想法的失败。可选对象的要点是您可以无条件地调用它们的内容,而无需测试内容是否存在。
如果您必须测试可选对象是否包含值,那么与普通null
测试相比,您没有做任何新的事情。
这是我详细解释可选对象的文章:C# 中 Option/Maybe 类型的自定义实现
这是包含代码和示例的 GitHub 存储库:https ://github.com/zoran-horvat/option
如果您不愿意使用重量级的 Option 解决方案,那么您可以轻松构建一个轻量级的解决方案。您可以创建自己的Option<T>
实现IEnumerable<T>
接口的类型,以便您可以利用 LINQ 扩展方法将调用变为可选。这是最简单的可能实现:
public class Option<T> : IEnumerable<T>
{
private readonly T[] data;
private Option(T[] data)
{
this.data = data;
}
public static Option<T> Create(T value)
{
return new Option<T>(new T[] { value });
}
public static Option<T> CreateEmpty()
{
return new Option<T>(new T[0]);
}
public IEnumerator<T> GetEnumerator()
{
return ((IEnumerable<T>)this.data).GetEnumerator();
}
System.Collections.IEnumerator
System.Collections.IEnumerable.GetEnumerator()
{
return this.data.GetEnumerator();
}
}
使用这种Option<T>
类型是通过 LINQ 完成的:
Option<Car> optional = Option<Car>.Create(myCar);
string color = optional
.Select(car => car.Color.Name)
.DefaultIfEmpty("<no car>")
.Single(); // you can call First(), too
您可以在这些文章中找到有关可选对象的更多信息:
您可以参考我的视频课程,了解有关如何使用Option
类型和其他方式简化控制流的更多详细信息:让您的 C# 代码在 .NET 中更具功能性和
战术性设计模式:控制流
第一个视频课程(让您的 C# 代码更具功能性)详细介绍了面向铁路的编程,包括Either
和Option
类型以及如何使用它们来管理可选对象和处理异常情况和错误。