有没有办法制作像这样的代码:
public class Func2<A, B>
{
private Func<A, B> f;
public Func2(Func<A, B> f)
{
this.f = f;
}
public object invoke(object obj, long l)
{
if (typeof(B) == typeof(long))
{
if (obj != null)
l = (long)obj;
return f((B)l); //error! cannot convert type 'long' to 'B'
} else {
return f((B)obj);
}
}
}
这里的问题是我不能直接将B转换为long而不先将B转换为对象。我试图不惜一切代价避免使用盒子,因为它会减慢对功能的快速操作。有没有办法实现这个目标?
我知道我实际上可以定义一个专门的Func2来专门处理B长的情况。但随着函数的优点的增长,long和对象的组合呈指数级增长 - 在实际用例中我也想支持双打!没有拳击有没有办法支持这个?也许有不安全的代码?
谢谢! Cauê
答案 0 :(得分:3)
您可以重载该方法,而不是将long
值转换为A
,您可以将代理转换为Func<long, B>
:
public class Func2<A, B> {
private Func<A, B> f;
public Func2(Func<A, B> f) {
this.f = f;
}
public B invoke(long a) {
if (typeof(A) == typeof(long)) {
return (f as Func<long, B>)(a);
} else {
throw new NotSupportedException();
}
}
public B invoke(object a) {
return f((A)a);
}
}
示例:
Func2<long, string> f = new Func2<long, string>(l => l.ToString());
Console.WriteLine(f.invoke(42)); // calls the invoke(long) method
Console.WriteLine(f.invoke("x")); // calls the invoke(object) method
答案 1 :(得分:0)
刚刚找到答案! :)
public object invoke(object obj, long l)
{
if (typeof(B) == typeof(long))
{
if (obj != null)
l = (long)obj;
Func<A, long> x = (Func<A, long>)(object)f;
return x(l);
} else {
return f((B)obj);
}
}
这样我们就不必对长对象进行自动装箱,但我们实际上将Func类型转换为接收我们指定的长度!
至于为什么我要尝试这样做,请阅读上述评论,我仍然会尝试找到最佳方法。
到目前为止,我们有以下Haxe代码:
var f:Int->Int->Float = function(x:Int, y:Int) return x + y + 0.5;
var f2:Dynamic->Dynamic->Dynamic = f; // ok
var f3:Dynamic->Int->Dynamic = f; //also ok
f2(10, 30); // ok - this will box the 10 and 30
我要做的是创建一个Fun3类型,它具有一个调用调用,它将同时获取盒装和未装箱的参数。如果底层函数真的接受未装箱的类型,它将首先尝试使用它们。