我正在尝试将委托类型作为类型参数传递,以便稍后我可以在代码中将其用作类型参数,如下所示:
// Definition
private static class Register
{
public static FunctionObject Create<T>(CSharp.Context c, T func)
{
return new IronJS.HostFunction<T>(c.Environment, func, null);
}
}
// Usage
Register.Create<Func<string, IronJS.CommonObject>>(c, this.Require);
然而,C#编译器抱怨:
The type 'T' cannot be used as type parameter 'a' in the generic type or method
'IronJS.HostFunction<a>'. There is no boxing conversion or type parameter
conversion from 'T' to 'System.Delegate'."
我尝试通过将“where T:System.Delegate”附加到函数来解决此问题,但是,您不能将System.Delegate用作类型参数的限制:
Constraint cannot be special class 'System.Delegate'
有谁知道如何解决这个冲突?
不工作(演员阵容中的参数和返回类型信息丢失):
Delegate d = (Delegate)(object)(T)func;
return new IronJS.HostFunction<Delegate>(c.Environment, d, null);
答案 0 :(得分:6)
如果你看https://github.com/fholm/IronJS/blob/master/Src/IronJS/Runtime.fs,你会看到:
and [<AllowNullLiteral>] HostFunction<'a when 'a :> Delegate> =
inherit FO
val mutable Delegate : 'a
new (env:Env, delegateFunction, metaData) =
{
inherit FO(env, metaData, env.Maps.Function)
Delegate = delegateFunction
}
换句话说,您不能使用C#或VB来编写函数,因为它需要使用System.Delegate
作为类型约束。我建议您使用F#编写函数或使用反射,如下所示:
public static FunctionObject Create<T>(CSharp.Context c, T func)
{
// return new IronJS.HostFunction<T>(c.Environment, func, null);
return (FunctionObject) Activator.CreateInstance(
typeof(IronJS.Api.HostFunction<>).MakeGenericType(T),
c.Environment, func, null);
}
答案 1 :(得分:1)
@Gabe是完全正确的,它与HostFunction上的类型约束有关&lt;'&gt;只在F#中有效的类(而不是C#或VB)。
您是否检查了Native.Utils中的功能?这是我们在运行时内部使用从代理创建函数的内容。特别是let CreateFunction (env:Env) (length:Nullable<int>) (func:'a when 'a :> Delegate) =
函数应该完全符合您的需要。
如果CreateFunction无法满足您的需求,请在http://github.com/fholm/IronJS/issues打开一张机票,其中包含您缺少的内容以及您希望如何实施该机票,我们会立即开始实施。
答案 2 :(得分:0)
作为2018年5月之后阅读此内容的任何人的更新:
从c#7.3(.Net Framework 4.7.2)开始, 现在可以使用where T : System.Delegate
作为对通用声明的约束,这意味着原始发布者现在可以能够做她在c#中试图做的事情-不必诉诸使用另一种.Net语言来构建类。
System.Enum
(在C#的早期版本中另一个完全缺失的约束)现在也可用。还有其他一些补充。