RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1309190
Accepted
Максим Фисман
Максим Фисман
Asked:2022-07-27 03:23:42 +0000 UTC2022-07-27 03:23:42 +0000 UTC 2022-07-27 03:23:42 +0000 UTC

将泛化限制为任何数字数据类型

  • 772
这个问题已经在这里得到了回答:
如何编写一个对所有数字类型都适用的方法/类? (3 个回答)
将 int、long、double、BigInteger 的方法组合成一个 3 个答案
1 年前关闭。

在 C# 中是否可以将函数泛型限制为数字?例如,我想创建一个 Bounds 结构来保存某物的最小和最大边界。限制只能是数字,但可以是 and int, and float, and double, 等等。

我有想法通过结构泛型来实现这一点,并将该泛型限制为仅给定的类型,如下所示:

struct Bounds<T> where T: int, float, double {
    T Min, Max;
    // Далее можно будет, например реализовать метод проверки числа в границах:
    bool isInBounds (T num)
        => num >= Min && num <= Max;
}

但是,这样的实现会引发错误:"int" не является допустимым ограничением. 似乎结构泛化根本不能成为约束!
如果没有,怎么可能引入这样的限制?
如果是这样,除了做这样的事情之外,是否有更漂亮的方法来引入类似的约束:

public struct Bounds <T> {
    T Min, Max;

    public Bounds<T> (T min, T max) {
        if (typeof(T) == typeof(int) || typeof(T) == typeof(float) || ...) {
            Min = min;
            ...
        }
        else 
            throw new Exception(...);
    }
}
c#
  • 1 1 个回答
  • 10 Views

1 个回答

  • Voted
  1. Best Answer
    VladD
    2022-07-27T06:37:29Z2022-07-27T06:37:29Z

    这取决于您要支持哪种操作。

    目前,还没有完全支持这样的接口INumeric,因为没有什么东西可以填充这个接口:在 C# 中,还没有对这样的运算符+或<接口中的运算符的支持。然而,这方面的工作正在进行中,随着语言的发展,这样的机会将会出现。这里[1]、[2]的工作正朝着这个方向进行,到目前为止,还只是在设计和理解它的外观方面。

    当出现这样的接口时INumeric,可以将其作为通用约束,同时进行加法、比较等操作。


    您原则上可以将运行时检查移动到静态构造函数中:

    struct Bounds<T>
    {
        static Bounds()
        {
            if (typeof(T) != typeof(int) &&
                typeof(T) != typeof(double) &&
                typeof(T) != typeof(float))
               throw new NotSupportedException(
                        "Bounds<> can be instantiated only with types int, double, float");
        }
    }
    

    那么每次实例化都不会花费时间Bounds<T>。

    如果您只需要一些功能并且并不真正关心漂亮的语法,您可能会考虑手动实现它,但效率可能会受到影响。这里有些例子:

    • 如何编写一个对所有数字类型都适用的方法/类?
    • C# 如何创建一个与 int 和 double 一样有效的类?
    • 实现 C# 矩阵

    根据名称Bounds,正如评论中正确建议的那样,只有一个可能对您来说就足够了IComparable<T>。在这种情况下,限制为数字类型没有多大意义,你可以写

    struct Bounds<T> where T : IComparable<T>
    {
        T Min, Max;
        static Comparer<T> comparer = Comparer<T>.Default; // использует IComparable<T>
    
        bool isInBounds (T num)
            => comparer.Compare(num, Min) >= 0 && comparer.Compare(num, Max) <= 0;
    }
    

    如果您需要更高级的操作,您可以使用前面提到的答案中的代码,或者从 Genumerics nuget包中获取现成的实现:

    using Genumerics;
    
    struct Bounds<T>
    {
        T Min, Max;
        public static Bounds<T> FromMidpointAndHalfWidth(T midpoint, T halfwidth)
        {
            if (Number.LessThan(halfwidth, Number.Zero<T>()))
                throw new ArgumentOutOfRangeException(nameof(halfwidth),
                                                      "Width should be not negative");
            return new Bounds<T>()
            {
                Min = Number.Subtract(midpoint, halfwidth),
                Max = Number.Add(midpoint, halfwidth)
            };
        }
    
        public bool IsInBounds(T num) =>
            Number.GreaterThanOrEqual(num, Min) && Number.LessThanOrEqual(num, Max);
    }
    
    • 7

相关问题

  • 使用嵌套类导出 xml 文件

  • 分层数据模板 [WPF]

  • 如何在 WPF 中为 ListView 手动创建列?

  • 在 2D 空间中,Collider 2D 挂在玩家身上,它对敌人的重量相同,我需要它这样当它们碰撞时,它们不会飞向不同的方向。统一

  • 如何在 c# 中使用 python 神经网络来创建语音合成?

  • 如何知道类中的方法是否属于接口?

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    表格填充不起作用

    • 2 个回答
  • Marko Smith

    提示 50/50,有两个,其中一个是正确的

    • 1 个回答
  • Marko Smith

    在 PyQt5 中停止进程

    • 1 个回答
  • Marko Smith

    我的脚本不工作

    • 1 个回答
  • Marko Smith

    在文本文件中写入和读取列表

    • 2 个回答
  • Marko Smith

    如何像屏幕截图中那样并排排列这些块?

    • 1 个回答
  • Marko Smith

    确定文本文件中每一行的字符数

    • 2 个回答
  • Marko Smith

    将接口对象传递给 JAVA 构造函数

    • 1 个回答
  • Marko Smith

    正确更新数据库中的数据

    • 1 个回答
  • Marko Smith

    Python解析不是css

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5