是否存在将我的泛型方法限制为数字类型的约束? [英] Is there a constraint that restricts my generic method to numeric types?

查看:36
本文介绍了是否存在将我的泛型方法限制为数字类型的约束?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

谁能告诉我是否有一种方法可以使用泛型将泛型类型参数 T 限制为仅:

  • Int16
  • Int32
  • Int64
  • UInt16
  • UInt32
  • UInt64

我知道 where 关键字,但找不到这些类型的接口,

类似于:

static bool IntegerFunction(T value) where T : Inumeric

解决方案

C# 不支持这个.Hejlsberg 在接受 Bruce Eckel 采访时描述了未实施该功能的原因:><块引用>

并且不清楚增加的复杂性是否值得您获得的小收益.如果你想做的事情在约束系统中没有直接支持,你可以用工厂模式来做.例如,您可以有一个 Matrix,并且在该 Matrix 中您想定义一个点积方法.那当然意味着您最终需要了解如何将两个 T 相乘,但是您不能说这是一个约束,至少在 T 时不是>intdoublefloat.但是你可以做的是让你的 MatrixCalculator 作为参数,并在 Calculator 中,有一个方法称为乘法.你去实现它,然后把它传递给 Matrix.

然而,这会导致代码相当复杂,用户必须为他们想要使用的每个 T 提供他们自己的 Calculator 实现.只要它不必是可扩展的,即如果您只想支持固定数量的类型,例如 intdouble,您就可以摆脱一个相对简单的界面:

var mat = new Matrix(w, h);

(GitHub Gist 中的最小实现.)

但是,一旦您希望用户能够提供他们自己的自定义类型,您就需要打开此实现,以便用户可以提供他们自己的 Calculator 实例.例如,要实例化一个使用自定义十进制浮点实现的矩阵,DFP,您必须编写以下代码:

var mat = new Matrix(DfpCalculator.Instance, w, h);

... 并实现 DfpCalculator 的所有成员:ICalculator.

不幸的是,另一种方法有相同的限制,那就是使用策略类,如 Sergey Shandar 的回答中所述.

Can anyone tell me if there is a way with generics to limit a generic type argument T to only:

  • Int16
  • Int32
  • Int64
  • UInt16
  • UInt32
  • UInt64

I'm aware of the where keyword, but can't find an interface for only these types,

Something like:

static bool IntegerFunction<T>(T value) where T : INumeric 

解决方案

C# does not support this. Hejlsberg has described the reasons for not implementing the feature in an interview with Bruce Eckel:

And it's not clear that the added complexity is worth the small yield that you get. If something you want to do is not directly supported in the constraint system, you can do it with a factory pattern. You could have a Matrix<T>, for example, and in that Matrix you would like to define a dot product method. That of course that means you ultimately need to understand how to multiply two Ts, but you can't say that as a constraint, at least not if T is int, double, or float. But what you could do is have your Matrix take as an argument a Calculator<T>, and in Calculator<T>, have a method called multiply. You go implement that and you pass it to the Matrix.

However, this leads to fairly convoluted code, where the user has to supply their own Calculator<T> implementation, for each T that they want to use. As long as it doesn’t have to be extensible, i.e. if you just want to support a fixed number of types, such as int and double, you can get away with a relatively simple interface:

var mat = new Matrix<int>(w, h);

(Minimal implementation in a GitHub Gist.)

However, as soon as you want the user to be able to supply their own, custom types, you need to open up this implementation so that the user can supply their own Calculator instances. For instance, to instantiate a matrix that uses a custom decimal floating point implementation, DFP, you’d have to write this code:

var mat = new Matrix<DFP>(DfpCalculator.Instance, w, h);

… and implement all the members for DfpCalculator : ICalculator<DFP>.

An alternative, which unfortunately shares the same limitations, is to work with policy classes, as discussed in Sergey Shandar’s answer.

这篇关于是否存在将我的泛型方法限制为数字类型的约束?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆