所以在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)
Ste*_*ary 12
摘要
这是简短的回答:
因此,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#语言.
你可以(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)
但我同意你可能不需要这个.
我有时也觉得我需要(整数)typedef 用于与 OP 类似的目的。
如果你不介意演员表是明确的(我实际上希望他们是)你可以这样做:
enum PeerId : int {};
也适用于byte, sbyte, short, ushort, uint, long,或ulong(显然)。
不完全是 的预期用途enum,但它确实有效。
从 C# 10 开始,您可以使用全局:
global using PeerId = System.Int32;
Run Code Online (Sandbox Code Playgroud)
它适用于所有文件。
它应该出现在所有不带全局修饰符的 using 指令之前。
请参阅using 指令。