【问题标题】:Implementing own data types in C# without enum?在没有枚举的情况下在 C# 中实现自己的数据类型?
【发布时间】:2014-09-23 18:26:35
【问题描述】:

内置数据类型和用户定义数据类型的主要区别在于:内置数据类型可以接受字面量值(直接插入代码中的值,这个过程也称为硬编码)。

那么是否可以创建与接受三个值的布尔值相同的自定义数据类型: 是/否/也许不使用枚举。

如以下代码:

MyCustomBoolean a = maybe;

我问上面的问题是因为我想了解 C# 中的内置数据类型是用核心语言(例如 C++ int、char...)指示的吗?

---更新---

对于第二个问题,让我问一个问题,让第二个问题更清楚:

我知道例如 string 是 System.String 的别名,但是 C# 中的纯字符串在没有 System.String 的情况下是否可以工作?

【问题讨论】:

  • 您无法更改语言的语法(根据定义)。 C# 不支持用户定义的文字(C++ 支持,但仅限于limited extent)。但是,您仍然可以获得看起来类似的代码,例如通过定义一个名为 maybeMyCustomBoolean 类型的变量。
  • 在 C# 中:不,完全不可能。尽管它们不会给您任何编译时安全性,但大致隐含的转换运算符更接近。您需要从任何其他现有类型转换的类型。在您的示例中,maybe 不是类型。这对编译器没有任何意义。所以这是不允许的。
  • @Cameron 我知道例如字符串是 System.String 的别名,但是 C# 中的纯字符串在没有 System.String 的情况下可以工作吗?
  • @Cameron C++11 也有 constexpr,它真的很强大,似乎是 OP 正在寻找的。​​span>
  • 作为一种解决方法,您可以使用可为空的布尔值 (bool?),其中 null 值表示可能。

标签: c# c++ types enums hard-coding


【解决方案1】:

没有办法完全按照您的要求执行此操作。但是,您可以在 C# 中创建 constant fields,它可以完成此结果(命名值),但只能使用 integral types 或字符串 - 换句话说,您已经可以用于编译时常量的东西。这对于 Magic Values 可能特别有用。

public const string Maybe = "Maybe";
public const int Maybe = 0;

解决此问题的一种方法是初始化静态readonly 字段或属性,尽管它不能用作真正的常量。例如

public static readonly MyCustomBoolean Maybe { get { return new MycustomBoolean(); } }
public static MyCustomBoolean Maybe = new MyCustomBoolean();

【讨论】:

  • but only with the integral types 不。您可以使用任何编译时文字,其中有一些非数字类型。
  • 非数字的,是的,但我故意提到了 Integral。为了清楚起见,用链接更新我的答案。
  • 我说那是错误的。对于不在该列表中的类型,有很多编译时文字。你甚至有一个你的答案正确的例子。正确的说法是 const 标识符(注意它实际上不是一个字段)可以初始化为任何编译时文字的值。
  • 好的,是的,显然字符串不算作“整数”
  • 字符串也不是唯一的例外。如果您想查看 C# 中有效编译时文字的更详细说明,请随意查看语言规范。也就是说,问题的重点是询问如何定义 他自己的 类型的自定义类型的编译时文字,这些类型还没有编译时文字。这并不能回答这个问题。
【解决方案2】:

对于这种特定情况,您可以使用可为空的布尔值。 使用以下典型操作:

bool? b = null
if (b.HasValue)
if (b.Value)
b = true

其中可能为空,或有HasValue == false

【讨论】:

    【解决方案3】:

    文字是 C# 语言的一个特性。您不能创建新的文字。

    您可能对其他编程语言感兴趣,例如 Nemerle,它允许您创建用户定义的文字,例如以下 XML 文字: https://github.com/rsdn/nemerle/wiki/XML-literals

    枚举和常量通常填补了 C# 的空白。对于更复杂的结构,您经常会看到使用了一些流畅的 API。

    当然,我们可以看到 C# 中缺少此功能意味着提供一种自然的方式来定义查询意味着需要更改 C# 语言规范以支持 LINQ。如果 C# 具有与 Nemerle 相似的元编程特性,那么它们可以在不改变语言语法的情况下实现与 LINQ 相同的目标。

    【讨论】:

    • 是的! LINQ 就是一个很好的例子。但是 LINQ 是如何用纯 C# 代码实现的呢?
    • @Amir 在使用 LINQ 时没有使用编译时文字。我看不出 LINQ 在这里有什么意义。
    • @Servy 请看下面的代码: int[] array = { 1, 2, 3, 6, 7, 8 }; // 查询表达式。 var elements = from element in array orderby element descending where element > 2 select element;
    • 它使用了 c# 核心语言中没有的词。
    • @Amir 这些词的核心语言。它们是关键字,而不是编译时常量值,但它们也在实际的 C# 语言规范中定义为上下文关键字。它们不是由 LINQ 定义的,也不是特定于 LINQ 的。随意查看 C# 语言规范的查询理解部分,自己阅读它们。
    猜你喜欢
    • 2021-09-27
    • 2020-09-12
    • 1970-01-01
    • 1970-01-01
    • 2015-12-24
    • 1970-01-01
    • 2010-12-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多