Java1.8正在接收Optional<T>类,它允许我们显式地声明方法何时可能返回空值,并“强制”它的使用者在使用它之前验证它是否不为空值(isPresent())。
我看到C#有Nullable<T>,它做了一些类似的事情,但是有基本的类型。它似乎用于DB查询,以区分值何时存在且为0,以及何时值不存在且为null。
但是似乎C#的Nullable<T>不适用于对象,只适用于基本类型,而Java的Optional<T>只适用于对象,不适用于基本类型。
在C#中是否有一个可以为空/可选的类,强制我们在提取和使用对象之前测试对象是否存在?
发布于 2013-04-25 02:14:48
不是用语言写的,但你可以自己写:
public struct Optional<T>
{
public bool HasValue { get; private set; }
private T value;
public T Value
{
get
{
if (HasValue)
return value;
else
throw new InvalidOperationException();
}
}
public Optional(T value)
{
this.value = value;
HasValue = true;
}
public static explicit operator T(Optional<T> optional)
{
return optional.Value;
}
public static implicit operator Optional<T>(T value)
{
return new Optional<T>(value);
}
public override bool Equals(object obj)
{
if (obj is Optional<T>)
return this.Equals((Optional<T>)obj);
else
return false;
}
public bool Equals(Optional<T> other)
{
if (HasValue && other.HasValue)
return object.Equals(value, other.value);
else
return HasValue == other.HasValue;
}
}请注意,您将无法模拟Nullable<T>的某些行为,例如将不带值的可空值装箱为null的能力,而不是装箱后的可空值箱,因为它具有对该行为(以及其他一些行为)的特殊编译器支持。
发布于 2016-09-26 02:42:23
在我看来,任何暴露HasValue属性的Option实现都是对整个思想的失败。optional对象的意义在于,您可以对其内容进行无条件调用,而无需测试内容是否存在。
如果您必须测试optional对象是否包含一个值,那么与常见的null测试相比,您并没有做什么新的事情。
下面是我详细解释可选对象的文章:Custom Implementation of the Option/Maybe Type in C#
下面是包含代码和示例的GitHub存储库:https://github.com/zoran-horvat/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类型和其他方法简化控制流的更多详细信息:Making Your C# Code More Functional和Tactical Design Patterns in .NET: Control Flow
第一个视频课程(Making Your C# Code More Functional)详细介绍了面向铁路的编程,包括Either和Option类型,以及如何使用它们来管理可选对象和处理异常情况和错误。
发布于 2016-03-26 19:33:16
在C#中有更好的选项类型实现。你可以在pluralsight.com的Zoran Horvat的Tactical design patterns in .NET中找到这个实现。它包括为什么和如何使用它的解释。其基本思想是实现option类作为IEnumerable<>接口的实现。
public class Option<T> : IEnumerable<T>
{
private readonly T[] data;
private Option(T[] data)
{
this.data = data;
}
public static Option<T> Create(T element)
{
return new Option<T>(new[] { element });
}
public static Option<T> CreateEmpty()
{
return new Option<T>(new T[0]);
}
public IEnumerator<T> GetEnumerator()
{
return ((IEnumerable<T>) this.data).GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
}https://stackoverflow.com/questions/16199227
复制相似问题