我真的很喜欢通用数字类型作为下面给出的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) => ...);
缺少:
dynamic
关键字在C#中有没有正确的方法呢?
我猜Java有一个Number
类可能符合我的要求,但我想知道C#是否有类似的东西。
我想C#中没有这样的东西,但我想我会确定。
答案 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
(仍属于类型安全,但在运行时与编译时相比)或double
或decimal
如果你想做数学而不是&# 39; t必须保持相同的类型。
答案 2 :(得分:1)
好消息:现在在 .NET 6 和 C# 10 中有一个解决方案,参见。 https://angular.io/api/core/APP_INITIALIZER
当你想要任何数字时,你可以使用 INumber<T>
。如果您需要任何特定的运算符,请使用相应的接口,例如IAdditionOperators
代表 a + b
或 IIncrementOperators
代表 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>