2011-01-26 48 views
2

有没有什么办法,使这样的工作代码:铸造类型参数为基本型无拳

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到长时间没有铸造B首先反对。我试图避免不惜一切代价,因为这会减慢很多功能的快速操作。那么有什么办法可以做到这一点?

我知道我实际上可以定义一个专门的Func2来专门处理B长的情况。但随着函数的长度增长,长和对象的组合将呈指数级增长 - 而且在实际使用情况下,我还希望支持双打!有没有什么办法可以在没有拳击的情况下支持这个?也许有不安全的代码?

谢谢! Cauê

+4

什么是你想在这里做?如果你让我们知道可能会有更好的方法 – 2011-01-26 17:34:12

+0

我正在为C#编写一个haXe(haxe.org)目标,并且我试图找到用C#代表HaXe函数类型的最佳方法。 HaXe函数类型与CLR不同,允许将Func 转换为Func (例如)。所以我试图找到一种能够在我们可以的时候调用无盒子参数的方法,并且当我们不知道类型时调用盒装版本。 – Waneck 2011-01-26 17:43:24

回答

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 
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 

我想要做的就是创建一个具有invoke调用,将采取两种盒装和拆箱参数的FUN3类型。如果底层函数真的接受无箱类型,它将首先尝试使用它们。

谢谢!