Передача делегата в качестве параметра типа и его использование вызывает ошибку CS0314

Я пытаюсь передать тип делегата в качестве параметра типа, чтобы затем использовать его в качестве параметра типа позже в коде, например:

// 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'."

Я попытался исправить это, добавив " где T: система.Делегировать " функции, однако, вы не можете использовать System.Делегировать как ограничение на параметры типа:

Constraint cannot be special class 'System.Delegate'

кто-нибудь знает как решить эту конфликт?

не работает (информация о аргументе и типе возврата теряется во время приведения):

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

2 ответов


Если вы посмотрите на 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, который действителен только в F# (а не C# или VB).

вы проверили функции в родной.Utils? Это то, что мы используем внутри среды выполнения для создания функций из делегатов. Особенно let CreateFunction (env:Env) (length:Nullable<int>) (func:'a when 'a :> Delegate) = функция должна делать именно то, что вам нужно.

Если CreateFunction не выполняет то, что вам нужно, откройте билет по адресу http://github.com/fholm/IronJS/issues с тем, что вам не хватает и как вы хотели бы, чтобы это было реализовано, и мы получим прямо на нем.