当前位置: 首页 > 编程语言 > C#

为什么数字类型不共享一个公共接口?分享

时间:2023-04-10 13:32:20 C#

为什么数字类型不共享一个公共接口?我最近遇到了这个问题,我想要一个函数来处理双精度数和整数,并且想知道为什么所有数字类型都没有通用接口(带有算术运算符和比较)。它会使Math.Min(存在于Math.Min重载中)之类的东西更方便。引入一个额外的接口是一个突破性的变化吗?编辑:我会考虑使用这个publicTAdd(Ta,Tb)whereT:INumber{returna+b;}或publicTRange(Tx,Tmin,Tmax)whereT:INumber{returnMax(x,Min(x,max),min);}如果你想做这种“泛型”运算,你对C#这样的强类型语言的选择是非常有限的。MarcGravell对该问题的描述如下:.NET2.0在.NET世界中引入了泛型,为现有问题的许多优雅解决方案打开了大门。通用约束可用于将类型参数限制为已知接口等,以确保对函数的访问——或者对于简单的相等/不等式测试,Comparer.Default和EqualityComparer.Default单例实现IComparer和IEqualityComparer分别允许我们在不知道的情况下比较元素排序关于“T”的任何事情。尽管如此,在运营商方面仍存在很大差距。因为运算符被声明为静态方法,所以没有所有数字类型都实现的IMath或类似的等效接口;事实上,运营商的灵活性会使这变得非常困难。更糟糕的是:许多原始类型的运算符甚至不作为运算符存在;相反,有直接的IL方法。使情况进一步复杂化的是,Nullable需要“提升运算符”的概念,其中内部“T”描述适用于可为空类型的运算符——但这是作为一种语言特性实现的,而不是由运行时实现的(以使反射更有趣)。但是,C#4.0引入了dynamic关键字,您可以使用它在运行时选择正确的重载:usingSystem;公共类程序{staticdynamicMin(dynamica,dynamicb){returnMath.Min(a,b);}staticvoidMain(string[]args){inti=Min(3,4);双d=最小(3.0,4.0);你应该知道,如果你找不到合适的重载来调用,这会在动态运行时消除类型安全,例如因为您正在混合类型,所以您可能会在运行时遇到异常。如果您想要类型安全,您可能需要查看MiscUtil库中可用的类,它们为基本操作提供通用运算符。请注意,如果您只是在执行特定操作之后,实际上可以使用内置类型已经实现的接口。例如,类型安全的通用Min函数可能如下所示:publicstaticTMin(paramsT[]values)whereT:IComparable{Tmin=values[0];foreach(variteminvalues.Skip(1)){if(item.CompareTo(min)即如何做2+2.35?返回4或4.35或4.349999?接口如何理解什么是适当的输出?你可以写扩展方法和使用重载来解决这个问题,但是如果我们想要为所有目的设置接口大小需要多长时间并且很难找到有用的功能,那么接口也增加了一些开销并且数字通常是底层计算所以需要快速的方法。我认为在你的情况下最好写一个扩展类:,分钟);}publicstaticTMin(thisTinput,paramsT[]param)whereT:class{returnnull;}privatestaticTMax(thisTinput,paramsT[]number)whereT:class{returnnull;我用whereT:class编译好吧,你不能在接口中定义运算符和结构(尽管它们支持接口)不能很好地与接口实现一起工作,因为这需要装箱和拆箱,当然这在纯粹的时候很困难表演数学。通过接口实现。我还想强调的是,当您将结构转换为其接口时,生成的对象是您执行操作的引用类型(装箱对象),而不是原始结构本身:interfaceIDoSomething{voidDoSomething();}structMyStruct:IDoSomething{publicMyStruct(intage){this.Age=age;公共诠释年龄;publicvoidDoSomething(){年龄++;}}publicvoidDoSomething(IDoSomethingsomething){something.DoSomething();当输入我的结构实例时,它被装箱(成为引用类型)并且我执行我的DoSomething操作,但我的结构的原始实例没有改变。根据Matthew的回答,注意3个调用之间的区别。voidDoSomething(refMyStructsomething){something.DoSomething();}staticvoidMain(string[]args){vars=newMyStruct(10);vari=(IDoSomething)s;做某事;//不会修改sDoSomething(i);//将修改iDoSomething(refs);//会修改s,但不会重新赋值}这不像引入接口那么简单,因为每种类型可用的运算符不同,而且并不总是均匀的(即DateTime+TimeSpan=>DateTime,DateTime-DateTime=>TimeSpan).在技??术层面上,这里可能涉及很多拳击等,而常规操作符是静态的。事实上,对于Min/Max,Comparer.Default.Compare(x,y)几乎可以满足您的所有期望。对于其他运算符:在.NET4.0中,dynamic在这里有很大的帮助:Tx=...,y=...;Tsum=(dynamic)x+(dynamic)y;但除此之外,“MiscUtil”通过Operator类一般支持运算符,即Tx=...,y=...;Tsum=Operator.Add(x,y);//其实Add问题在于系统结构中如何存储数字,不同的数字类型处理不同。对于初学者,您的措辞是错误的,界面不起作用,但我认为您得到的是您希望数字成为的松散类型。只是开始为什么你不想这样做,考虑整数类型是它们可以表示的值范围的一对一映射,而浮点类型有一个persision和exponent组件,因为有很多浮点数。语言开发人员必须在语言设计中做出一些非常基本且可能错误的假设。有关更多信息,请查看这篇关于浮点数学的文章。这是“强类型语言”的主要特征。这可以防止每分钟出现数十亿次错误。当然,我们希望int与double完全不同。以上是C#学习教程:Whydon'tthenumerictypesshareacommoninterface?如果所有分享的内容对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: