首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >C#.Net中的可选返回

C#.Net中的可选返回
EN

Stack Overflow用户
提问于 2013-04-25 02:09:53
回答 13查看 51K关注 0票数 67

Java1.8正在接收Optional<T>类,它允许我们显式地声明方法何时可能返回空值,并“强制”它的使用者在使用它之前验证它是否不为空值(isPresent())。

我看到C#有Nullable<T>,它做了一些类似的事情,但是有基本的类型。它似乎用于DB查询,以区分值何时存在且为0,以及何时值不存在且为null。

但是似乎C#的Nullable<T>不适用于对象,只适用于基本类型,而Java的Optional<T>只适用于对象,不适用于基本类型。

在C#中是否有一个可以为空/可选的类,强制我们在提取和使用对象之前测试对象是否存在?

EN

回答 13

Stack Overflow用户

回答已采纳

发布于 2013-04-25 02:14:48

不是用语言写的,但你可以自己写:

代码语言:javascript
运行
复制
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的能力,而不是装箱后的可空值箱,因为它具有对该行为(以及其他一些行为)的特殊编译器支持。

票数 36
EN

Stack Overflow用户

发布于 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扩展方法将调用变为可选的。下面是最简单的实现:

代码语言:javascript
运行
复制
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完成的:

代码语言:javascript
运行
复制
Option<Car> optional = Option<Car>.Create(myCar);
string color = optional
  .Select(car => car.Color.Name)
  .DefaultIfEmpty("<no car>")
  .Single();  // you can call First(), too

您可以在这些文章中找到有关可选对象的更多信息:

  • Custom Implementation of the Option/Maybe Type in C#
  • Understanding the Option (Maybe) Functional Type
  • How to Reduce Cyclomatic Complexity: Option Functional Type

您可以参考我的视频课程,了解有关如何使用Option类型和其他方法简化控制流的更多详细信息:Making Your C# Code More FunctionalTactical Design Patterns in .NET: Control Flow

第一个视频课程(Making Your C# Code More Functional)详细介绍了面向铁路的编程,包括EitherOption类型,以及如何使用它们来管理可选对象和处理异常情况和错误。

票数 36
EN

Stack Overflow用户

发布于 2016-03-26 19:33:16

在C#中有更好的选项类型实现。你可以在pluralsight.com的Zoran Horvat的Tactical design patterns in .NET中找到这个实现。它包括为什么和如何使用它的解释。其基本思想是实现option类作为IEnumerable<>接口的实现。

代码语言:javascript
运行
复制
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();
    }
}
票数 13
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16199227

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档