C#中是否有类似于TypeScript中的Never类型?

6

我想知道是否有C#中等价于TypeScript的never类型

例如,使用TS编写以下代码会在构建时出现错误。

enum ActionTypes {
    Add,
    Remove
}

type IAdd = {type: ActionTypes.Add};
type IRemove = {type: ActionTypes.Remove};

type IAction = IAdd | IRemove;

const ensureNever = (action: never) => action;

function test(action: IAction) {
    switch (action.type) {
        case ActionTypes.Add:
            break;
        default:
            ensureNever(action);
            break;
    }
}

错误信息是:类型“IRemove”的参数不能赋给类型“never”的参数。

当有人在一个文件中改变逻辑并且我想确保这个新情况在任何地方都被处理时,这非常有用。

在c#中有什么方法可以做到这一点吗?(我搜索了一下,但没有找到任何东西)

这是我目前的进展...

using System;
class Program
{
    private enum ActionTypes
    {
        Add,
        Remove
    }

    interface IAction {
        ActionTypes Type { get; }
    }

    class AddAction : IAction
    {
        public ActionTypes Type
        {
            get {
                return ActionTypes.Add;
            }
        }
    }

    class RemoveAction : IAction
    {
        public ActionTypes Type
        {
            get
            {
                return ActionTypes.Remove;
            }
        }
    }

    static void Test(IAction action)
    {
        switch (action.Type)
        {
            case ActionTypes.Add:
                Console.WriteLine("ActionTypes.Add");
                break;
            default:
                // what should I put here to be sure its never reached?
                Console.WriteLine("default");
                break;
        }
    }

    static void Main(string[] args)
    {
        var action = new RemoveAction();
        Program.Test(action);
    }
}

我希望在构建时而不是运行时发现错误。


2
TypeScript是一个单词,没有空格。 - user47589
我认为如果有人更改枚举或指定一个你不想允许的有效枚举值,就没有办法在编译时出现错误。 - Rufus L
1
在C#中没有空类型。 - Lee
@RufusL 谢谢!那就是我的问题。我有同样的假设。无论如何,我希望也许有人知道如何做到这一点。 - Peter
1个回答

1

很遗憾,我认为C#编译器还不够智能。即使在switch语句的默认情况下抛出一个新的异常,也不会出现关于缺少ActionTypes.Remove情况的编译时错误。

我发现这篇MSDN博客文章提到了“never”类型,它“不太可能成为主流CLR语言的特性。”


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接