C# 泛型常量
有没有类似这个C++模板的东西?
template <int A>
class B
{
int f()
{
return A;
}
}
我想让 B<1>、B<2> 等(例如元组)的每个实例成为不同的类型。
Is there something similar to this C++ template?
template <int A>
class B
{
int f()
{
return A;
}
}
I want to make every instance of B<1>, B<2>, etc (eg tuple) a different type.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
简短的回答是不。
与 C++ 模板不同,它不适合 C# 泛型的工作方式。
.net 泛型不是语言功能,而是运行时功能。运行时知道如何从特殊的泛型字节码实例化泛型,与 C++ 模板可以描述的内容相比,这是相当有限的。
将此与 C++ 模板进行比较,后者基本上使用替换类型实例化类的整个 AST。可以将基于 AST 的实例化添加到运行时,但它肯定比当前的泛型复杂得多。
如果没有值类型数组(仅存在于不安全代码中)等功能,使用此类参数的递归模板实例化或模板专业化也不会很有用。
The short answer is no.
It doesn't fit the way C# generics, as apposed to C++ templates, work.
The .net generics are not a language feature, they are a runtime feature. The runtime knows how to instantiate generics from special generic bytecode which is rather restricted compared to what C++ templates can describe.
Compare this with C++ templates, which basically instantiate the whole AST of the class using substituted types. It'd be possible to add AST based instantiation to the runtime, but it'd certainly be much more complex than the current generics.
Without features like value-type arrays (which only exist in unsafe code), recursive template instantiation or template specialization using such parameters wouldn't be very useful either.
解决此限制的方法是定义一个类,该类本身公开您感兴趣的文字值。例如:
用法:
A workaround to this limitation is to define a class which itself exposes the literal value you are interested in. For example:
Usage:
C# 不像 C++ 那样支持非类型泛型参数。
C# 泛型比 C++ 模板简单得多,功能也少得多。 MSDN 提供了C++ 模板和 C# 泛型之间的差异的简洁列表。
C# does not support non-type generic parameters like C++ does.
C# generics are far simpler and less capable than C++ templates. MSDN has a succinct list of Differences Between C++ Templates and C# Generics.
C# 泛型在运行时专门化,而 C++ 模板在编译时处理以创建全新类型。鉴于此,运行时根本不具备处理非类型参数的功能(这不仅仅是 C# 问题)。
C# generics are specialized at run-time, whereas C++ templates are processed at compile-time to make an entirely new type. Given this, the runtime simply doesn't have the features to process non-type parameters (it's not just a C# issue).
对于 C# 10,有些东西有点接近:
遗憾的是,这并不能保证
Constant
实际上是常量,并且您需要为要使用的所有数字定义类型。但是,它确实允许您区分B
和B
几乎不等价,但至少有一些
注意,您需要添加
;true
到您的 .csproj 才能正常工作,因为abstract static
接口方法仍处于预览状态With C# 10, there's something that comes sort of close:
This does not guarantee that
Constant
is actually constant sadly, and you need to define types for all numbers you want to use. However it does allow you to discriminateB<Constant1>
andB<Constant2>
Not nearly an equivalent but something at least
Note that you need to add
<EnablePreviewFeatures>true</EnablePreviewFeatures>
to your .csproj for this to work, asabstract static
Interface methods are still in preview根据您想要实现的目标,以下方法可能有用。底层集合的大小由抽象属性决定。
The following approach may be useful depending on what you're trying to accomplish. The size of the underlying collection is determined by an abstract property.