为什么不号码类型都有一个共同的界面? [英] Why don't number types share a common interface?

查看:91
本文介绍了为什么不号码类型都有一个共同的界面?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近遇到的问题跑了,我想要一个函数,在两个双打和整数的工作,并想知道,为什么是所有数字类型(含算术运算符和比较)没有通用接口。



这将使书写功能,如 Math.Min (存在于一个极大重载)的方式更方便易。



会引入额外的接口是一个重大更改



编辑:
我想用这个像

 市民不要再增加< T>(T A,T b)若T:i编号
{
返回A + b;
}

 公开范围标准< T>(T X,T最小,T最大),其中T:i编号
{
收益最大(X,闵(X,最大值)分钟);
}


解决方案

如果你想要做这样的这种通用算术在强类型语言的选项,如C#是相当有限的。马克Gravell 描述的问题如下




.NET 2.0中引入泛型到.NET世界,这打开门让现有的问题很多优雅的解决方案。通用约束可以用来限制类型参数已知接口等,以确保获得的功能 - 或者简单的等号/不等测试的Comparer< T> .DEFAULT EqualityComparer< T> .DEFAULT 单身落实的IComparer< T> 的IEqualityComparer< T> 分别为(让我们为实例中的元素进行排序,而无需知道有关T的问题,任何东西)。



通过这一切,虽然,仍然有很大的差距,当涉及到运营商。由于运营商被声明为静态方法,没有 IMath< T> 或类似的对应接口,所有的数字类型实现;实际上,运营商的灵活性将使这个很难以有意义的方式来做到。更糟糕的:对许多原始类型,甚至不存在,因为运营商经营的;而不是有直接的IL方法。为了使形势更加复杂,可为空<>要求解禁商,其中内T讲述了适用于可空类型的运营商的概念 - 但是这是作为一个语言功能,而不是由提供运行时(使反射更有趣)。




不过,C#4.0中引入了动态关键字,你可以用它来选择在运行时正确过载:

 使用系统; 

公共类节目
{
静态动态敏(动态一,动态B)
{
返回Math.Min(A,B);
}

静态无效的主要(字串[] args)
{
INT I =最小值(3,4);
双D =最小值(3.0,4.0);
}
}

您应该知道,这将删除类型安全和如果动态运行时无法找到合适的超载打电话,例如,你可能会在运行时异常因为你混合类型。



如果你想获得类型安全,你可能希望在 MiscUtil 库提供基本操作的通用运营商



请注意,如果你是只有在特定的操作你实际可以使用的内置类型已实现的接口。例如,一个类型安全的通用最小函数可能看起来像这样:

 公共静态T最小< T>(PARAMS T []值),其中T:IComparable的< T> 
{
T最小=值[0];
的foreach(在values.Skip VAR项(1))
{
如果(LT item.CompareTo(分钟); 0​​)
MIN =项目;
}
返回分钟;
}


I recently ran across the problem, that I wanted a function to work on both doubles and integers and wondered, why there is no common interface for all number types (containing arithmetic operators and comparisons).

It would make writing functions like Math.Min (which exist in a gazillion overloads) way more convinient.

Would introducing an additional interface be a breaking change?

Edit: I think about using this like

public T Add<T>(T a, T b) where T: INumber
{
    return a+b;
}

or

public T Range<T>(T x, T min, T max) where T:INumber
{
    return Max(x, Min(x, max), min);
}

解决方案

If you want to do such kind of "generic" arithmetics your option in a strongly-typed language such as C# are quite limited. Marc Gravell described the problem as follows:

.NET 2.0 introduced generics into the .NET world, which opened the door for many elegant solutions to existing problems. Generic constraints can be used to restrict the type-arguments to known interfaces etc, to ensure access to functionality - or for simple equality/inequality tests the Comparer<T>.Default and EqualityComparer<T>.Default singletons implement IComparer<T> and IEqualityComparer<T> respectively (allowing us to sort elements for instance, without having to know anything about the "T" in question).

With all this, though, there is still a big gap when it comes to operators. Because operators are declared as static methods, there is no IMath<T> or similar equivalent interface that all the numeric types implement; and indeed, the flexibility of operators would make this very hard to do in a meaningful way. Worse: many of the operators on primitive types don't even exist as operators; instead there are direct IL methods. To make the situation even more complex, Nullable<> demands the concept of "lifted operators", where the inner "T" describes the operators applicable to the nullable type - but this is implemented as a language feature, and is not provided by the runtime (making reflection even more fun).

However, C# 4.0 introduced the dynamic keyword which you can use to choose the correct overload at runtime:

using System;

public class Program
{
    static dynamic Min(dynamic a, dynamic b)
    {
        return Math.Min(a, b);        
    }

    static void Main(string[] args)
    {
        int i = Min(3, 4);
        double d = Min(3.0, 4.0);
    }
}

You should be aware that this removes type-safety and you might get exceptions at runtime if the dynamic runtime cannot find a suitable overload to call, e.g. because you mixed types.

If you want to get type-safety you might want to have a look at the classes available in the MiscUtil library providing generic operators for basic operations.

Please note that if you are only after specific operations you actually might use the interfaces that the built-in types already implement. For example, a type-safe generic Min function could look like this:

public static T Min<T>(params T[] values) where T : IComparable<T>
{
    T min = values[0];
    foreach (var item in values.Skip(1))
    {
        if (item.CompareTo(min) < 0)
            min = item;
    }
    return min;
}

这篇关于为什么不号码类型都有一个共同的界面?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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