什么是C#等同于Haskell的新类型? [英] What is C#'s equivalent to Haskell's newtype?

查看:117
本文介绍了什么是C#等同于Haskell的新类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

- 程序中的其他地方
login :: Int - > Bool
login n = hasAccess n - Typechecker不会抱怨

A <$ c

 类型检查器被认为是一个不同的类型:$ c $> newtype  newtype UserId = UserId Int 
hasAccess :: UserId - > Bool
hasAccess(UserId id)= { - stuff - }

- 程序中的其他地方
login :: Int - > Bool
登录n = hasAccess n - Typechecker会抱怨,n不是UserId!

在C#中,可以使用顶级定义类型同义词, / code>声明:

 使用UserId = Int; 

但是,强类型的编译器检查类型别名似乎不存在于C#中默认。我已经研究了使用T4模板和CodeDOM生成自动代码生成以生成类封装器,但我并不知道如何将它们完全整合到我的编程流程中。



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

  //类似这样的东西? 
使用Int.UserId;

/ *其他地方* /
var id = new UserId(5);

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

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

$ b $不,C#不具备这样的功能。

  public struct UserId 
{
public int Id {得到;私人设置; }

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

这样,编译器确实将 UserId int 作为不同的类型。此外,考虑到您的 int 实际上是用户ID,您可以在 UserId 中添加更多方法,这些方法是有意义的。另请注意,这对运行时没有任何影响,使用带有单个 int 字段的结构不会导致使用 int 直接。



编辑:由于您询问了T4,如果您使用Visual Studio,一个新的T4文本模板,将扩展到(C#) - 代码并将自动编译。该模板将在您每次保存时执行。


In Haskell, there's two ways of providing an alias for types: type and newtype. type provides a type synonym, which means the synonym is regarded by the type checker as exactly the same as the original 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

A newtype is similar, but is regarded by the type checker as a different type:

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 !

In C#, you can define type synonyms with a top-level using declaration:

using UserId = Int;

However, a strongly-typed, compiler-checked type alias does not seem to be present in C# by default. I've looked into automatic code generation with T4 templates and CodeDOM to generate a class wrapper, but I don't really know how I could cleanly integrate those into my programming flow.

Ideally, I would like to be able to say on a top-level:

// Something like this?
using Int.UserId;

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

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

This kicks the code generation into gear at compile-time. If that's not possible or provides a chicken-and-egg issue for IntelliSense, an automatic compilation option that runs every x minutes (or a button or whatever) would be nice.

解决方案

No, C# does not have such a feature. The closest you can get to this are structs.

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

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

This way, the compiler indeed treats UserId and int as different types. Furthermore, you can add more methods to UserId that make sense given the fact that your int is effectively a user id. Note as well that this does not have any effect on the runtime, using a struct with a single int field does not cause any overhead against using int directly.

Edit: Because you asked about T4, if you are working with Visual Studio, you can easily create a new T4 Text template that will expand to (C#)-code and will be compiled automatically. The template will be executed everytime you save it.

这篇关于什么是C#等同于Haskell的新类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆