繁体   English   中英

什么是C#相当于Haskell的新类型?

[英]What is C#'s equivalent to Haskell's newtype?

在Haskell中,有两种方法可以为类型提供别名: typenewtype type提供类型同义词 ,这意味着类型检查器将同义词视为与原始类型完全相同:

type UserId = Int
hasAccess :: UserId -> Bool
hasAccess id = {-- stuff --}

-- Elsewhere in the program
login :: Int -> Bool
login n = hasAccess n -- Typechecker won't complain

newtype类似,但类型检查器将其视为不同类型:

newtype UserId = UserId Int
hasAccess :: UserId -> Bool
hasAccess (UserId id) = {-- stuff --}

-- Elsewhere in the program
login :: Int -> Bool
login n = hasAccess n -- Typechecker will complain, n isn't a UserId !

在C#中,您可以使用顶级using声明来定义类型同义词:

using UserId = Int;

但是,默认情况下,C#中似乎不存在强类型的编译器检查类型别名。 我已经研究了使用T4模板和CodeDOM自动生成代码以生成类包装器,但我真的不知道如何将它们干净地集成到我的编程流程中。

理想情况下,我希望能够在顶层说:

// Something like this?
using Int.UserId;

/* Elsewhere */
var id = new UserId(5);

public bool HasAccess( UserId id )
{
    /* Stuff */
}

这使代码生成在编译时生成 如果这不可能或者为IntelliSense提供鸡蛋问题,那么每x分钟(或按钮或其他)运行的自动编译选项会很好。

不,C#没有这样的功能。 你可以得到最接近的结构。

public struct UserId
{
    public int Id { get; private set; }

    public UserId(int id) : this() { Id = id; }
}

这样,编译器确实将UserIdint视为不同的类型。 此外,您可以向UserId添加更多有意义的方法,因为您的int实际上是用户ID。 还要注意,这对运行时没有任何影响,使用带有单个int字段的结构不会导致任何直接使用int开销。

编辑:因为您询问了T4,如果您正在使用Visual Studio,您可以轻松创建一个新的T4文本模板,该模板将扩展为(C#) - 代码并将自动编译。 每次保存时都会执行模板。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM