如何在C#中为内置类型添加别名?

voi*_*ter 16 c# alias

所以在C++中,我习惯于:

typedef int PeerId;
Run Code Online (Sandbox Code Playgroud)

这允许我创建一个更自我文档的类型,但另外还允许我在不改变所有代码的情况下随时使PeerId表示不同的类型.如果我愿意,我甚至可以将PeerId变成一个班级.这种可扩展性是我想要在C#中使用的,但是我无法弄清楚如何在C#中为'int'创建别名.

我想我可以使用using语句,但它只在我认为的当前文件中有作用域,因此不起作用(别名需要在多个文件之间可访问而不重新定义).我也无法从内置类型派生一个类(但通常这是我对别名ref或类型,如List或Dictionary)所做的.我不知道我能做什么.有任何想法吗?

Cha*_*ion 19

您需要使用完整的类型名称,如下所示:

using DWORD = System.Int32;
Run Code Online (Sandbox Code Playgroud)

  • 这个解决方案没有处理他的问题的这一部分:'我想我可以使用using语句,但它只在我认为的当前文件中有作用域,因此不起作用(别名需要在多个文件之间可访问)没有被重新定义)' (13认同)

Ste*_*ary 12

摘要

这是简短的回答:

  • Typedef实际上是编译时代码生成器使用的变量.
  • C#旨在避免添加代码生成语言结构.

因此,typedef的概念不适合C#语言.

答案很长

在C++中,它更有意义:C++最初是作为一个预编译器,它吐出C代码,然后编译.这个"代码生成器"开始仍然具有现代C++特性的效果(即,模板本质上是用于在编译时生成类和函数的图灵完备语言).在这种情况下,typedef是有意义的,因为它是获取编译时类型工厂的"结果"或"返回"类型的"算法"的一种方法.

在这种奇怪的元语言中(Boost之外很少有人掌握),typedef实际上是一个变量.

您所描述的内容不那么复杂,但您仍在尝试将typedef用作变量.在这种情况下,它用作输入变量.因此,当其他代码使用typedef时,它实际上并没有直接使用该类型.相反,它充当编译时代码生成器,基于typedef的输入变量构建类和方法.即使您忽略C++模板并只看C typedef,效果也是一样的.

C++和生成编程

C++被设计成一种多范式语言(OO和程序,但在Boost问世之前不起作用).有趣的是,模板已经发展出一种意想不到的范式:生成性编程.(生成式编程在C++之前就已存在,但C++使它很受欢迎).生成程序实际上是元程序 - 在编译时 - 生成所需的类和方法,这些类和方法又被编译成可执行文件.

C#和生成编程

我们的工具正朝着同一个方向缓慢发展.当然,反射发射可以用于"手动"生成编程,但是非常痛苦.LINQ提供程序使用表达式树的方式本质上非常具有生成性.T4模板非常接近,但仍然不足.如果它可以与某种类型的变量(例如typedef)结合使用,那么希望成为C#vNext一部分的"编译器即服务"似乎最有希望.

这个难题的一部分仍然缺失:生成程序需要某种自动触发机制(在C++中,这由隐式模板实例化处理).

但是,在C#语言中使用任何类型的"代码生成器"(如C++模板)可能明显不是 C#的目标(可能为了可理解性;很少有C++程序员理解C++模板).这可能是T4而不是C#所满足的利基.

结论(重复摘要)

所有这些都是这样说的:

  • Typedef是代码生成器使用的变量.
  • C#旨在避免添加代码生成语言结构.

因此,typedef的概念不适合C#语言.

  • 提供非常丰富的信息,但它不需要我不知道的任何信息,也不会实际回答我的初步问题.我只是提到typedef,给大家一个我正在思考/期待的例子.别名不一定需要编译时间,可以采用多种形式,例如派生.如果我能做到这一点:"公共类PeerId:int {}",那就足够了,完美地解决了我的问题. (3认同)

Mat*_*hen 8

你可以(ab)使用隐式转换:

struct PeerId
{
    private int peer;

    public static implicit operator PeerId(int i)
    {
        return new PeerId {peer=i};
    }

    public static implicit operator int(PeerId p)
    {
        return p.peer;
    }
}
Run Code Online (Sandbox Code Playgroud)

这与int占用相同的空间,您可以这样做:

PeerId p = 3;
int i = p;
Run Code Online (Sandbox Code Playgroud)

但我同意你可能不需要这个.


dan*_*mon 7

我有时也觉得我需要(整数)typedef 用于与 OP 类似的目的。

如果你不介意演员表是明确的(我实际上希望他们是)你可以这样做:

enum PeerId : int {};

也适用于byte, sbyte, short, ushort, uint, long,ulong(显然)。

不完全是 的预期用途enum,但它确实有效。


App*_*Web 5

从 C# 10 开始,您可以使用全局

global using PeerId = System.Int32;
Run Code Online (Sandbox Code Playgroud)

它适用于所有文件。

它应该出现在所有不带全局修饰符的 using 指令之前。

请参阅using 指令