Передача объекта Delegate в метод с параметром Func <> - PullRequest
3 голосов
/ 30 октября 2009

У меня есть метод Foo4, который принимает параметр типа Func <>. Если я передаю параметр анонимного типа, я не получаю ошибки. Но если я создаю и передаю объект типа «делегат», который ссылается на метод с правильной подписью, я получаю ошибку компилятора. Я не могу понять, почему я получаю ошибку в этом случае.

class Learn6
    {
        delegate string Mydelegate(int a);
        public void Start()
        {
            Mydelegate objMydelegate = new Mydelegate(Foo1);

            //No Error
            Foo4(delegate(int s) { return s.ToString(); });

            //This line gives compiler error.
            Foo4(objMydelegate);

        }

        public string Foo1(int a) { return a.ToString();}



        public void Foo4(Func<int, string> F) { Console.WriteLine(F(42)); }
    }

Ответы [ 4 ]

8 голосов
/ 30 октября 2009

Это работает, если вы передаете ссылку на метод напрямую:

Foo4(Foo1);

Это связано с тем, что фактические делегаты с одинаковой формой изначально не считаются совместимыми. Если контракты неявные, компилятор выводит контракт и сопоставляет их. Если они явные (например, объявленные типы), никакой вывод не выполняется - это просто разные типы.

Это похоже на:

public class Foo
{
    public string Property {get;set;}
}

public class Bar
{
    public string Property {get;set;}
}

Мы видим, что два класса имеют одинаковую сигнатуру и являются "совместимыми", но компилятор видит их как два разных типа, и ничего более.

4 голосов
/ 30 октября 2009

Поскольку Func<int, string> и MyDelegate - это разные объявленные типы. Они оказываются совместимыми с одним и тем же набором методов; но между ними нет явного преобразования.

0 голосов
/ 29 декабря 2009

зависит от сценария, но в общем случае нет смысла хранить тип Mydelegate, просто везде используйте Func :)

0 голосов
/ 30 октября 2009
        //This line gives compiler error.
        Foo4(objMydelegate);

        //This works ok.
        Foo4(objMydelegate.Invoke);
...