Передача объекта Delegate в метод с помощью Func < > параметр

StackOverflow https://stackoverflow.com/questions/1648082

Вопрос

У меня есть метод 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)); }
    }
Это было полезно?

Решение

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

Foo4(Foo1);

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

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

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

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

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

Другие советы

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top