Hik*_*ari 44 .net c# nullable optional
Java 1.8正在接收Optional类,它允许我们明确说明方法何时可以返回空值并"强制"其使用者isPresent()
在使用它之前验证它是否为null().
我看到C#有Nullable,它做了类似的事情,但有基本类型.它似乎用于数据库查询,以区分值何时存在,并且当它不存在时为0并且为空.
但似乎C#的Nullable不适用于对象,仅适用于基本类型,而Java的Optional仅适用于对象而不适用于基本类型.
在C#中是否有Nullable/Optional类,这迫使我们在提取和使用它之前测试对象是否存在?
Zor*_*vat 28
在我看来,任何Option
暴露HasValue
财产的实施都是整个想法的失败.可选对象的要点是,您可以无条件地调用其内容,而无需测试内容是否存在.
如果您必须测试可选对象是否包含值,那么与常见null
测试相比,您没有做任何新的事情.
以下是我正在详细解释可选对象的文章:C#中的Option/Maybe Type的自定义实现
这里是带有代码和示例的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();
}
}
Run Code Online (Sandbox Code Playgroud)
使用此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
Run Code Online (Sandbox Code Playgroud)
您可以在这些文章中找到有关可选对象的更多信息
您可以参考我的视频课程,了解有关如何使用Option
类型和其他方法简化控制流程的更多详细信息:在.NET中制作C#代码更多功能和
战术设计模式:控制流程
第一个视频课程(让您的C#代码更具功能性)详细介绍了面向铁路的编程,包括Either
和Option
类型以及它们如何用于管理可选对象和处理特殊情况和错误.
Ser*_*rvy 21
不是语言,不,但你可以自己做:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,您将无法模拟某些行为Nullable<T>
,例如能够将没有值的可空值设置为null,而不是盒装可空,因为它具有对该(以及其他一些)行为的特殊编译器支持.
Luk*_*och 13
在C#中有更好的选项类型实现.您可以通过pluralsight.com上的Zoran Horvat在.NET中的战术设计模式中找到这种实现方式.它包括解释为何以及如何使用它.基本思想是将选项类实现为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();
}
}
Run Code Online (Sandbox Code Playgroud)