Generics и действие делегат - PullRequest
1 голос
/ 28 марта 2011

У меня есть следующий код:

public void generate()
{
  base.generateFoo(Method); // How can i indicate the type here?
}

public void Method<T>(T t , IDictionary<T, SomeObject> coll) : where T : ISomething
{
 // do something
}


class MyBase
{
  public void generateFoo<T>(Action<T, IDictionary<T, SomeObject>> Method) : where T : ISomething
  {
     Method.invoke(ObjectThatImplementsT, DictionaryWIthTKey);
  }
}

Я получаю сообщение об ошибке, например не могу преобразовать ObjectThatImplementsT в T.

Могу ли я передать универсальный метод в качестве параметра другому методу?

В чем здесь проблема?

Спасибо.

Ответы [ 3 ]

2 голосов
/ 28 марта 2011

Возможно, вам просто нужно указать тип:

public void generate()
{
   base.generateFoo<YourType>(Method);
}

При этом - приведенный выше код, как написано, не будет компилироваться, поскольку generateFoo не является ни универсальным методом, ни универсальным классом, поэтому возможно, что вышеприведенный не будет работать. Предполагается, что generateFoo определен как универсальный метод (принимает тип T).

1 голос
/ 28 марта 2011

Все вышеперечисленное применимо, множество незначительных правок (почему бы вам не скомпилировать образец самостоятельно, чтобы мы могли знать, какие «проблемы» являются поддельными и в чем действительно заключается ваш вопрос?!)

Вотбит компиляции - обратите внимание на три варианта вызова generateFoo:

using System.Collections.Generic;
using System;

namespace X 
{ 
    class Y : MyBase
    {
        public static void Main(string[]args) { }

        public void generate()
        {
            base.generateFoo<Something>(Method<Something>); // works
            base.generateFoo<Something>(Method); // works as well
            base.generateFoo(Method<Something>); // doesn't (cannot be inferred)
        }

        public void Method<T>(T t , IDictionary<T, SomeObject> coll) 
            where T : ISomething
        {
            // do something
        }

    }

    class MyBase
    {
        public void generateFoo<T>(Action<T, IDictionary<T, SomeObject>> Method) 
            where T : class, ISomething
        {
            Method.Invoke((T) null, new Dictionary<T,SomeObject>());
        }
    }
    internal interface ISomething {}
    internal class Something : ISomething {}
    internal class SomeObject {}
}
1 голос
/ 28 марта 2011

Вы можете сделать generateFoo родовым для T с теми же ограничениями, что и для Method. Ваш пример на самом деле не скомпилируется иначе, так как T неизвестен MyBase (если у вас нет класса с именем T в известном пространстве имен).

...