Delegado Func sem tipo de retorno


561

Todos os delegados do Func retornam um valor. Quais são os delegados do .NET que podem ser usados ​​com métodos que retornam nulos?

Respostas:


760

Todos os delegados da Func retornam algo; todos os delegados da ação retornam nulos.

Func<TResult> não aceita argumentos e retorna TResult:

public delegate TResult Func<TResult>()

Action<T> recebe um argumento e não retorna um valor:

public delegate void Action<T>(T obj)

Action é o delegado mais simples e simples:

public delegate void Action()

Há também Func<TArg1, TResult>e Action<TArg1, TArg2>(e outros até 16 argumentos). Todos esses (exceto Action<T>) são novos no .NET 3.5 (definido em System.Core).


11
Para sua informação, a próxima versão da biblioteca de classes base incluirá os tipos Func e Action que suportam mais de quatro parâmetros formais. Não me lembro exatamente de quão grande eles ficam.
Eric Lippert

88
No .NET 4.0, eles agora chegam a 8 parâmetros. Se eles continuarem assim, na próxima versão ele subirá para onze !! 11 !!!
Michiel van Oosterhout 15/05

9
Na verdade, parece que eles chegam a 16 em 4.0.
precisa saber é o seguinte

7
1, 4, 16, 64, 256, 1024, 4096, 16384, 65536, ... isso indica claramente que o compilador precisará ser capaz de lidar com mais argumentos para uma função do que atualmente em algum momento no futuro !
23412 Chris Morgan

6
Na verdade, Tustin2121 está certo, eles subiram para 16 parâmetros (mais um tipo de retorno no caso de Func<,,, ... ,>) no .NET 4.0, mas os últimos oito tipos de cada "série" são definidos em System.Core.dll, não em mscorlib.dll, portanto, esse seria o motivo porque michielvoo não os viu. No entanto, nenhum Func ou Ação foi adicionado nas versões 4.5 e 4.5.1 do .NET. Essa sequência se tornará A170836 ou A170875 ? Fique ligado.
Jeppe Stig Nielsen

83

... não aceita argumentos e tem um tipo de retorno nulo?

Eu acredito que Actioné uma solução para isso.


47

Todos os delegados do Func usam pelo menos um parâmetro

Isso não é verdade. Todos eles usam pelo menos um argumento de tipo, mas esse argumento determina o tipo de retorno.

Portanto, Func<T>não aceita parâmetros e retorna um valor. Use Actionou Action<T>quando não desejar retornar um valor.


27

Experimente System.Func<T>eSystem.Action


1
Eu não acho que o argumento 0 e outros enfeites existem no .Net 2.0, no entanto.
2727 Brian

1
É estranho: o Func não existe no .Net 2.0, embora Predicate e Action existam.
Joel Coehoorn

2
Para o .NET 2.0, use o delegado MethodInvoker.
Trevor Elliott

O .NET 2 também tinha (ou tem) um tipo de delegado Converter<TInput, TOutput>semelhante ao posterior Func<T, TResult>. Foi usado no List<>.ConvertAllmétodo que projetava todos os elementos de um List<>objeto em outro e colocou todos os "valores de função" em um novo List<>. (Mais tarde, seria costumam usar Linq Selectpara isso.)
Jeppe Stig Nielsen

0

Ocasionalmente, você deseja escrever um delegado para manipulação de eventos; nesse caso, você pode tirar vantagem do System.EvenHandler<T>que aceita implicitamente um argumento do tipo object, além do segundo parâmetro que deve derivar EventArgs. EventHandlers retornarávoid

Pessoalmente, achei isso útil durante o teste para criar um retorno de chamada único em um corpo de função.


0

... não aceita argumentos e tem um tipo de retorno nulo?

Se você está escrevendo System.Windows.Forms, também pode usar:

public delegate void MethodInvoker()

0

Uma maneira muito fácil de chamar sub-rotinas de retorno e não retorno. está usando Func e Action, respectivamente. (consulte também https://msdn.microsoft.com/en-us/library/018hxwa8(v=vs.110).aspx )

Tente este exemplo

using System;

public class Program
{
    private Func<string,string> FunctionPTR = null;  
    private Func<string,string, string> FunctionPTR1 = null;  
    private Action<object> ProcedurePTR = null; 



    private string Display(string message)  
    {  
        Console.WriteLine(message);  
        return null;  
    }  

    private string Display(string message1,string message2)  
    {  
        Console.WriteLine(message1);  
        Console.WriteLine(message2);  
        return null;  
    }  

    public void ObjectProcess(object param)
    {
        if (param == null)
        {
            throw new ArgumentNullException("Parameter is null or missing");
        }
        else 
        {
            Console.WriteLine("Object is valid");
        }
    }


    public void Main(string[] args)  
    {  
        FunctionPTR = Display;  
        FunctionPTR1= Display;  
        ProcedurePTR = ObjectProcess;
        FunctionPTR("Welcome to function pointer sample.");  
        FunctionPTR1("Welcome","This is function pointer sample");   
        ProcedurePTR(new object());
    }  
}

1
Obrigado por este trecho de código, que pode fornecer ajuda imediata e limitada. Uma explicação adequada melhoraria bastante seu valor a longo prazo , mostrando por que essa é uma boa solução para o problema e a tornaria mais útil para futuros leitores com outras perguntas semelhantes. Por favor edite sua resposta para adicionar alguma explicação, incluindo as suposições que você fez.
iBug
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.