简体   繁体   English

如何定义基本类型的通用类型限制?

[英]How to define generic type limit to primitive types?

I have the following method with generic type:我有以下通用类型的方法:

T GetValue<T>();

I would like to limit T to primitive types such as int, string, float but not class type.我想将 T 限制为原始类型,例如 int、string、float,但不是 class 类型。 I know I can define generic for class type like this:我知道我可以像这样为 class 类型定义泛型:

C GetObject<C>() where C: class;

I am not sure if it is possible for primitive types and how if so.我不确定原始类型是否可行以及如何实现。

You can use this to limit it to value types: 您可以使用它将其限制为值类型:

where C: struct

You also mention string. 你还提到了字符串。 Unfortunately, strings won't be allowed as they are not value types. 不幸的是,不允许字符串,因为它们不是值类型。

Actually this does the job to certain extend: 实际上,这在一定程度上完成了工作:

public T Object<T>() where T :
   struct, IComparable, IFormattable, IConvertible, IComparable<T>, IEquatable<T>

To limit to numeric types you can get some useful hints of the following samples defined for the ValueType class 要限制数值类型,您可以获得为ValueType类定义的以下示例的一些有用提示

这是你要找的东西:

T GetObject<T>() where T : struct;

There is no generic constraint that matches that set of things cleanly. 没有通用约束可以干净地匹配这组事物。 What is it that you actually want to do? 你真的想做什么? For example, you can hack around it with runtime checks, such as a static ctor (for generic types - not so easy for generic methods)... 例如,您可以通过运行时检查来解决它,例如静态ctor(对于泛型类型 - 对于泛型方法来说不那么容易)......

However; 然而; most times I see this, it is because people want one of: 大多数时候我看到这一点,这是因为人们想要一个:

  • to be able to check items for equality: in which case use EqualityComparer<T>.Default 能够检查项目是否相等:在这种情况下使用EqualityComparer<T>.Default
  • to be able to compare/sort items: in which case use Comparer<T>.Default 能够比较/排序项目:在这种情况下使用Comparer<T>.Default
  • to be able to perform arithmetic: in which case use MiscUtil 's support for generic operators 能够执行算术:在这种情况下使用MiscUtil通用运算符的支持

What are you actually trying to do in the method? 你在这个方法中真正想做什么? It could be that you actually need C to implement IComparable, or someother interface. 可能实际上你需要C来实现IComparable或其他一些接口。 In which case you want something like 在这种情况下你想要的东西

T GetObject<T> where T: IComparable

I'm under the same need, I want to create a method that should retrieve a List where T should be a primitive type like int, double, decimal, etc...我有同样的需要,我想创建一个方法来检索一个列表,其中 T 应该是原始类型,如 int、double、decimal 等......

Based on this Microsoft documentation: https://learn.microsoft.com/en-us/do.net/csharp/language-reference/builtin-types/unmanaged-types基于此 Microsoft 文档: https://learn.microsoft.com/en-us/do.net/csharp/language-reference/builtin-types/unmanaged-types

Looks like the right approach is to use看起来正确的方法是使用

where T : unmanaged

quoting:引用:

A type is an unmanaged type if it's any of the following types:如果类型是以下任何类型,则该类型是非托管类型:

sbyte, byte, short, ushort, int, uint, long, ulong, char, float, double, decimal, or bool Any enum type Any pointer type Any user-defined struct type that contains fields of unmanaged types only and, in C# 7.3 and earlier, is not a constructed type (a type that includes at least one type argument) sbyte、byte、short、ushort、int、uint、long、ulong、char、float、double、decimal 或 bool 任何枚举类型 任何指针类型 任何用户定义的结构类型,仅包含非托管类型的字段,在 C# 7.3和更早的,不是构造类型(至少包含一个类型参数的类型)

Also important quote:还有重要的引述:

Beginning with C# 7.3, you can use the unmanaged constraint to specify that a type parameter is a non-pointer, non-nullable unmanaged type.从 C# 7.3 开始,可以使用非托管约束来指定类型参数是非指针、不可为空的非托管类型。

Beginning with C# 8.0, a constructed struct type that contains fields of unmanaged types only is also unmanaged...从C# 8.0开始,只包含非托管类型字段的构造结构类型也是非托管的...

如果您需要可以使用为托管类型保留的语言功能(例如 sizeof 运算符)的类型,请使用“非托管”。

where C: unmanaged

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM