将委托作为类型参数传递并使用它会引发错误CS0314

本文关键字:CS0314 错误 参数传递 类型 | 更新日期: 2023-09-27 17:57:58

我正试图将委托类型作为类型参数传递,以便稍后在代码中使用它作为类型参数,如下所示:

// 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.Delegation作为类型参数的限制:

Constraint cannot be special class 'System.Delegate'

有人知道如何解决这场冲突吗?

不起作用(参数和返回类型信息在强制转换过程中丢失):

Delegate d = (Delegate)(object)(T)func;
return new IronJS.HostFunction<Delegate>(c.Environment, d, null);

将委托作为类型参数传递并使用它会引发错误CS0314

如果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);
}   

@Gabe是完全正确的,它与HostFunction<'上的类型约束有关a> 类,该类仅在F#(而不是C#或VB)中有效。

你检查过Native.Utils中的函数吗?它是我们在运行时内部使用的,用于从委托创建函数。尤其是let CreateFunction (env:Env) (length:Nullable<int>) (func:'a when 'a :> Delegate) =函数应该完全满足您的需要。

如果CreateFunction不能满足您的需求,请在http://github.com/fholm/IronJS/issues了解您所缺少的内容以及您希望如何实现它,我们将立即着手。

作为2018年5月之后阅读本文的人的更新:

从c#7.3(.Net Framework 4.7.2)开始,现在可以使用where T : System.Delegate作为泛型声明的约束,这意味着原始发布者现在可以在c#中做她试图做的事情,而不必使用另一种.Net语言构建类。

System.Enum(c#早期版本中另一个严重遗漏的约束)现在也可用了。还有一些其他的补充。

https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/generics/constraints-on-type-parameters#delegate-限制