C# 不使用装箱将类型参数强制转换为基本类型

C# 不使用装箱将类型参数强制转换为基本类型,c#,generics,optimization,casting,boxing,C#,Generics,Optimization,Casting,Boxing,有没有办法让这样的代码起作用: 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))

有没有办法让这样的代码起作用:

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);
        }
    }
}
public类函数2
{
私人职能;
公共职能2(职能f)
{
这个。f=f;
}
公共对象调用(对象对象,长l)
{
if(类型(B)=类型(长))
{
如果(obj!=null)
l=(长)obj;
返回f((B)l);//错误!无法将类型“long”转换为“B”
}否则{
返回f((B)obj);
}
}
}
这里的问题是,如果不先将B转换为object,我就不能直接将B转换为long。我试图不惜一切代价避免使用box,因为它会减慢函数上的许多快速操作。那么,有什么办法可以实现这一点呢

我知道我实际上可以定义一个专门的Func2来专门处理B是长函数的情况。但是随着函数的算术性增长,long和对象的组合呈指数增长——在实际用例中,我还希望支持double!。有没有办法不打拳击就支持这一点?可能是不安全代码

谢谢大家!!
Cauê

刚刚找到了答案!:)


我要做的是创建一个Fun3类型,它有一个调用,该调用将同时接受装箱参数和未装箱参数。如果基础函数确实接受未绑定类型,它将首先尝试使用它们。

您可以重载该方法,而不是将
long
值强制转换为
A
,您可以将委托强制转换为
Func

public类函数2{
私人职能;
公共职能2(职能f){
这个。f=f;
}
公共B调用(长a){
if(类型(A)=类型(长)){
申报表(f为职能)(a);
}否则{
抛出新的NotSupportedException();
}
}
公共B调用(对象a){
返回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
func2f=newfunc2(l=>l.ToString());
Console.WriteLine(f.invoke(42));//调用invoke(long)方法
Console.WriteLine(f.invoke(“x”));//调用调用(对象)方法

您想在这里做什么?如果你让我们知道可能有更好的方法,我正在为C#编写一个haXe(haXe.org)目标,我正在试图找到用C#表示haXe函数类型的最佳方法。与CLR不同的是,HaXe函数类型允许将Func转换为Func(例如)。因此,我试图找到一种方法,在我们可以的时候调用unbox参数,在我们不知道类型的时候调用box版本。谢谢!!!我不会重载这个方法,因为这意味着我必须重载所有可能的类型组合(对于2种类型,这很容易,但是想想当你有一个5或6的算术函数时!),但是谢谢,这真的解决了问题!
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
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