C#中是否有通用数字类型?

时间:2016-06-29 12:29:22

标签: c# .net

我真的很喜欢通用数字类型作为下面给出的Func<TInput, THere, TResult>的第二个泛型类型参数,所以我可以提供一个整数,一个双精度或一个十进制数,当我喜欢的时候。

var _resultSelectors = new Dictionary<string, Func<DateTime, /*here*/ double, DateTime>>();

// so I can do
_resultSelector.Add("foo", (DateTime dt, int x) => ...);
_resultSelector.Add("bar", (DateTime dt, double d) => ...);
_resultSelector.Add("gar", (DateTime dt, float f) => ...);
_resultSelector.Add("har", (DateTime dt, decimal d) => ...);

缺少:

  1. 制作自己的类型;或
  2. 使用对象和装箱值类型并将其拆箱;或
  3. 使用dynamic关键字
  4. 在C#中有没有正确的方法呢?

    我猜Java有一个Number类可能符合我的要求,但我想知道C#是否有类似的东西。

    我想C#中没有这样的东西,但我想我会确定。

3 个答案:

答案 0 :(得分:11)

不,没有。泛型和算术运算(+-*/等)根本无法协同工作。这是一个多次出现的问题,C#设计委员会从未解决过(公平地说,这个功能也需要在CLR上工作,正如Eric Lippert在回答中进一步指出的那样)。

值得一提的是,如果您检查.NET Framework的源代码,您会发现在某个开发阶段有一个IArithmetic<T>接口,但它已被废弃;见here

您可以在此SO answer中了解有关它的更多信息。

答案 1 :(得分:5)

即使包含数字类型的基本类型或界面,因为您已将约束包裹在Func中,它对您没有任何好处。 Func的输入类型是逆变的,因此它的参数可以比我们声明的更多。

换句话说,您不能像Func<DateTime, ValueType, DateTime>一样用Func<DateTime, int, DateTime>取代IEnumerable<T>(您可以替换IEnumerable<ValueType> 1}} IEnumerable<int>

我认为你最好的赌注是dynamic(仍属于类型安全,但在运行时与编译时相比)或doubledecimal如果你想做数学而不是&# 39; t必须保持相同的类型。

答案 2 :(得分:1)

C# 10 和 .NET 6:2021 年 11 月以后的解决方案

好消息:现在在 .NET 6 和 C# 10 中有一个解决方案,参见。 https://angular.io/api/core/APP_INITIALIZER

当你想要任何数字时,你可以使用 INumber<T>。如果您需要任何特定的运算符,请使用相应的接口,例如IAdditionOperators 代表 a + bIIncrementOperators 代表 a++

注意:在我回答时,此功能只是一个预览。微软将在 .NET 6 的最终版本中保留这一点,因为他们仍然希望允许打破机会。要使用该功能,必须在项目配置中启用预览功能:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <EnablePreviewFeatures>true</EnablePreviewFeatures>
    <LangVersion>preview</LangVersion>
    <OutputType>Exe</OutputType>
    <TargetFramework>net6.0</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="System.Runtime.Experimental" Version="6.0.0-preview.7.21377.19" />
  </ItemGroup>

</Project>