Передача делегата в качестве параметра типа и его использование приводит к ошибке CS0314 - PullRequest
8 голосов
/ 29 мая 2011

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

// 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);

Ответы [ 3 ]

6 голосов
/ 31 мая 2011

Если вы посмотрите на 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 голос
/ 08 июня 2011

@ 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 с тем, что вам не хватает и какхотелось бы, чтобы это было реализовано, и мы получим это.

0 голосов
/ 16 мая 2019

Как обновление для всех, кто читает это после мая 2018 года:

Начиная с c # 7.3 (.Net Framework 4.7.2), теперь можно использовать where T : System.Delegate в качестве ограничения для общего объявления, что означает, что оригинальный плакат теперь сможет делать то, что она пыталась сделать в C # - не прибегая к созданию класса с другим языком .Net.

System.Enum (еще одно крайне пропущенное ограничение в более ранних версиях c #) теперь также доступно. Также есть пара других дополнений.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...