Desculpe por fazer uma pergunta de noob. Estou lendo C# em profundidade, onde o autor escreve em 9.4.3 inferência de tipo de duas fases
static void PrintConvertedValue<TInput,TOutput>
(TInput input, Converter<TInput,TOutput> converter)
{
Console.WriteLine(converter(input));
}
// ...
PrintConvertedValue("I'm a string", x => x.Length);
TInput
não depende de nenhum parâmetro de tipo não fixo, então é fixo em string.
Eu estava tentando esse código, mas falhou:
public class Program
{
public void foo<type1, type2>(List<type1> foo,Func<type1, type2> bar) { }
public static void Main(string[] args)
{
new Program().foo(new List<int>(), (string str)=> str.Lenth);
}
}
Eu queria saber se alguém poderia me mostrar o exemplo "TInput depende de qualquer parâmetro de tipo não fixo", ou seja, como o próprio parâmetro de tipo pode ser dependente de outro parâmetro de tipo para ser inferido?
Qualquer pergunta sobre inferência de tipo genérico não é uma pergunta de "novato" - não que haja algo errado em ser novo em uma linguagem.
A inferência de tipos é extremamente complicada - e tenho medo de dizer que é provável que até mesmo a especificação C# ainda não esteja precisamente correta, embora eu ache que ela esteja melhorando com o tempo (por meio dos esforços da equipe Microsoft C# e do grupo de trabalho ECMA responsável pela padronização, bem como de membros interessados da comunidade). No rascunho da especificação C# 8 (sim, estamos atrasados), a inferência de tipos está na seção 12.6.3 .
O relacionamento específico "depende de" sobre o qual você está perguntando é 12.6.3.6 :
Como exemplo disso - acho que já faz muito tempo que não olho para isso com tantos detalhes* - considere esta declaração de método genérico realmente simples:
Agora considere esta chamada de método:
Aqui, para o argumento
x => x.Length
,TSource
é um tipo de entrada, e eTResult
é um tipo de saída. EntãoTResult
depende diretamente deTSource
.Então, esse é aquele pequeno pedaço de terminologia em particular - onde há muito em inferência de tipo. Mas, sério: não se preocupe com os detalhes . Eu tive que procurar tudo isso no padrão - não é terminologia (ou procedimento) que eu lembro de cabeça, de forma alguma.
Geralmente, adoto a abordagem de só me preocupar com os detalhes se estou realmente confuso sobre o porquê de algo que eu esperaria que funcionasse não funcionar. Eu acho que para 99,9% dos desenvolvedores C#, a menos que você esteja escrevendo um compilador C# (ou um livro sobre C#), a vida é muito curta. (E se você estiver escrevendo um livro sobre C#, hoje em dia eu recomendaria consultar a especificação em vez de tentar fazer um trabalho melhor de explicá-la você mesmo... Eu mesmo seguirei esse conselho na próxima vez.)