Resolver erros e avisos relacionados a parâmetros de tipo genérico e argumentos de tipo genérico

Este artigo aborda os seguintes erros do compilador:

  • CS0080: restrições não são permitidas em declarações não genéricas.
  • CS0081: a declaração de parâmetro de tipo deve ser um identificador e não um tipo.
  • CS0224: um método com vararg não pode ser genérico, estar em um tipo genérico ou ter um parâmetro params.
  • CS0304: Não é possível criar uma instância do tipo de variável porque ela não tem a new() restrição.
  • CS0305: o uso do tipo genérico requer argumentos de tipo N.
  • CS0306: O tipo pode não ser usado como um argumento de tipo.
  • CS0307: o 'identificador' não pode ser usado com argumentos de tipo.
  • CS0308: O tipo ou método não genérico não pode ser usado com argumentos de tipo.
  • CS0310: O tipo deve ser um tipo não abstrato com um construtor público sem parâmetros para usá-lo como parâmetro no tipo ou método genérico.
  • CS0311: O tipo não pode ser usado como parâmetro T de tipo no tipo genérico ou método. Não há nenhuma conversão de referência implícita de 'type1' para 'type2'.
  • CS0312: O tipo 'type1' não pode ser usado como parâmetro de tipo em um tipo genérico ou método. O tipo anulável 'type1' não satisfaz a restrição de 'constraint'.
  • CS0313: O tipo 'type1' não pode ser usado como parâmetro de tipo no tipo ou método genérico. O tipo anulável 'type1' não satisfaz a restrição de 'constraint'. Tipos anuláveis não podem satisfazer nenhuma restrição de interface.
  • CS0314: O tipo não pode ser usado como parâmetro de tipo no tipo genérico ou no método. Não há conversão boxing nem conversão de parâmetro de tipo de 'type' para 'constraint'.
  • CS0315: O tipo não pode ser usado como parâmetro de tipo T no tipo ou método genérico. Não há conversão boxing de 'type' para 'constraint'.
  • CS0401: A new() restrição deve ser a última restrição restritiva especificada.
  • CS0403: não é possível converter nulo em parâmetro de tipo porque ele pode ser um tipo de valor não anulável. Considere usar default(T) em vez disso.
  • CS0405: restrição duplicada para o parâmetro de tipo.
  • CS0406: A restrição de tipo de classe 'constraint' deve vir antes de qualquer outra restrição.
  • CS0409: Uma cláusula de restrição já foi especificada para o parâmetro de tipo "parâmetro de tipo". Todas as restrições para um parâmetro de tipo devem ser especificadas em uma única cláusula where.
  • CS0411: os argumentos de tipo para o método 'method' não podem ser inferidos do uso. Tente especificar explicitamente os argumentos de tipo.
  • CS0412: Parâmetro: um parâmetro, uma variável local ou uma função local não pode ter o mesmo nome que um parâmetro de tipo de método.
  • CS0413: O parâmetro de tipo não pode ser usado com o as operador porque ele não tem uma restrição de tipo de classe nem uma restrição class .
  • CS0417: Identificador: não é possível fornecer argumentos ao criar uma instância de um tipo de variável.
  • CS0449: As restrições class, struct, unmanaged, notnull e default não podem ser combinadas ou duplicadas, e devem ser especificadas primeiro na lista de restrições.
  • CS0450: Parâmetro de tipo: não é possível especificar simultaneamente uma classe de restrição e a restrição ou .
  • CS0451: A new() restrição não pode ser usada com a restrição struct .
  • CS0452: O tipo "nome do tipo" deve ser um tipo de referência para usá-lo como parâmetro 'nome do parâmetro' no tipo genérico ou método 'genérico'.
  • CS0453: O tipo 'nome do tipo' deve ser um tipo de valor não anulável para usá-lo como parâmetro 'nome do parâmetro' no tipo genérico ou método 'genérico'.
  • CS0454: dependência de restrição circular envolvendo o Parâmetro de Tipo 1 e o Parâmetro de Tipo 2.
  • CS0455: o parâmetro Type herda restrições conflitantes 'constraint1' e 'constraint2'.
  • CS0456: o parâmetro de tipo 'type parameter 1' tem a restrição 'struct' para que 'type parameter 1' não possa ser usado como uma restrição para 'type parameter 2'.
  • CS0693: O parâmetro de tipo 'type parameter' tem o mesmo nome que o parâmetro de tipo do tipo externo 'type'.
  • CS0694: o parâmetro Type tem o mesmo nome que o tipo ou método que contém.
  • CS0695: 'type' não pode implementar 'interface1' e 'interface2' porque eles podem se unificar em algumas substituições de parâmetro de tipo.
  • CS0698: um tipo genérico não pode derivar do tipo porque é uma classe de atributo.
  • CS0699: 'generic' não define o parâmetro de tipo 'identifier'.
  • CS0701: 'identifier' não é uma restrição válida. Um tipo usado como uma restrição deve ser uma interface, uma classe não lacrada ou um parâmetro de tipo.
  • CS0702: a restrição não pode ser uma classe especial.
  • CS0703: acessibilidade inconsistente: o tipo de restrição é menos acessível que a declaração.
  • CS0704: Não é possível fazer pesquisa de membro não virtual em 'type' porque é um parâmetro de tipo.
  • CS0706: tipo de restrição inválido. Um tipo usado como uma restrição deve ser uma interface, uma classe não lacrada ou um parâmetro de tipo.
  • CS0717: classe estática: classes estáticas não podem ser usadas como restrições.
  • CS0718: 'type': tipos estáticos não podem ser usados como argumentos de tipo.
  • CS1720: A expressão sempre causará um System.NullReferenceException porque o valor padrão de "tipo genérico" é nulo.
  • CS1763: 'parameter' é do tipo 'type'. Um valor de parâmetro padrão de um tipo de referência diferente de cadeia de caracteres só pode ser inicializado com nulo.
  • CS1948: A variável de intervalo 'name' não pode ter o mesmo nome que um parâmetro de tipo de método.
  • CS1960: modificador de variação inválido. Somente parâmetros de interface e de tipo delegado podem ser especificados como variante.
  • CS1961: Variação inválida: o parâmetro de tipo deve ser covariantemente válido em 'type'. 'type parameter' é contravariante.
  • CS3024: o tipo de restrição 'type' não é compatível com CLS.
  • CS7002: uso inesperado de um nome genérico.
  • CS8322: não é possível passar argumento com tipo dinâmico para função local genérica com argumentos de tipo inferidos.
  • CS8375: A restrição 'new()' não pode ser usada com a restrição 'não gerenciada'.
  • CS8377: O tipo 'type' deve ser um tipo de valor não anulável, bem como todos os campos, em qualquer nível de aninhamento, para que possa ser usado como parâmetro 'parameter' no tipo genérico ou método 'generic'.
  • CS8379: o parâmetro de tipo 'type parameter 1' tem a restrição 'unmanaged' para que 'type parameter 1' não possa ser usado como uma restrição para 'type parameter 2'.
  • CS8380: 'type': não é possível especificar uma classe de restrição e a restrição 'não gerenciada'.
  • CS8387: o parâmetro de tipo 'type parameter' tem o mesmo nome que o parâmetro de tipo do método externo 'method'.
  • CS8389: omitir o argumento de tipo não é permitido no contexto atual.
  • CS8427: Enums, classes e estruturas não podem ser declarados em uma interface que tenha um parâmetro de tipo 'in' ou 'out'.
  • CS8665: O método 'method' especifica uma restrição 'class' para o parâmetro de tipo 'type parameter', mas o parâmetro de tipo correspondente 'type parameter' do método 'method' substituído ou implementado explicitamente não é um tipo de referência.
  • CS8666: O método 'method' especifica uma restrição 'struct' para o parâmetro de tipo 'type parameter', mas o parâmetro de tipo correspondente 'type parameter' do método 'method' substituído ou explicitamente implementado não é um tipo de valor não anulável.
  • CS8822: o método 'method' especifica uma restrição 'default' para o parâmetro de tipo 'type parameter', mas o parâmetro de tipo correspondente 'type parameter' do método 'method' substituído ou explicitamente implementado é restrito a um tipo de referência ou um tipo de valor.
  • CS8823: A restrição 'padrão' é válida somente em métodos de substituição e implementação de interface explícita.
  • CS8893: 'type' não é um tipo de convenção de chamada válido para 'UnmanagedCallersOnly'.
  • CS8894: não é possível usar 'type' como um parâmetro ou tipo de retorno em um método atribuído com 'UnmanagedCallersOnly'.
  • CS8895: os métodos atribuídos com 'UnmanagedCallersOnly' não podem ter parâmetros de tipo genérico e não podem ser declarados em um tipo genérico.
  • CS8896: 'UnmanagedCallersOnly' só pode ser aplicado a métodos estáticos não abstratos, não virtuais ou funções locais estáticas.
  • CS9011: A palavra-chave delegate não pode ser usada como uma restrição. Você quis dizer System.Delegate?
  • CS9012: Palavra-chave recordinesperada. Você quis dizer record struct ou record class?
  • CS9338: Acessibilidade inconsistente: o tipo é menos acessível que a classe.

Declaração e nomenclatura de parâmetro de tipo

  • CS0080: restrições não são permitidas em declarações não genéricas.
  • CS0081: a declaração de parâmetro de tipo deve ser um identificador e não um tipo.
  • CS0412: Parâmetro: um parâmetro, uma variável local ou uma função local não pode ter o mesmo nome que um parâmetro de tipo de método.
  • CS0693: o parâmetro de tipo 'type parameter' tem o mesmo nome que o parâmetro de tipo do tipo externo 'type'.
  • CS0694: o parâmetro Type tem o mesmo nome que o tipo ou método que contém.
  • CS0699: 'generic' não define o parâmetro de tipo 'identifier'.
  • CS1948: A variável de intervalo 'name' não pode ter o mesmo nome que um parâmetro de tipo de método.
  • CS8387: o parâmetro de tipo 'type parameter' tem o mesmo nome que o parâmetro de tipo do método externo 'method'.
  • CS9012: Palavra-chave recordinesperada. Você quis dizer record struct ou record class?

Esses erros estão relacionados à forma como você declara e nomeia parâmetros de tipo em tipos e métodos genéricos. Os nomes de parâmetro de tipo devem ser identificadores válidos, não devem entrar em conflito com outros identificadores no escopo e devem aparecer na lista de parâmetros de tipo da declaração.

  • Remova a cláusula de restrição de declarações não genéricas (CS0080). A where cláusula só pode ser usada em tipos genéricos e métodos que declaram parâmetros de tipo. Se você precisar aplicar restrições, primeiro adicione parâmetros de tipo à declaração de tipo ou método.
  • Substitua nomes de tipo reais por identificadores em declarações de parâmetro de tipo (CS0081). Você deve declarar parâmetros de tipo usando identificadores (como T, TKeyou TValue) em vez de tipos concretos (como int ou string). A finalidade de um parâmetro de tipo é servir como um espaço reservado que o compilador substitui por tipos reais quando o tipo ou método genérico é usado.
  • Renomeie parâmetros de tipo, variáveis locais, parâmetros ou variáveis de intervalo para evitar conflitos de nomenclatura (CS0412, CS0694, CS1948). Os nomes de parâmetro de tipo não podem sombrear identificadores no mesmo escopo e não podem corresponder ao nome do tipo ou método que contém. As variáveis de intervalo LINQ também não podem reutilizar o nome do parâmetro de tipo de um método. Esses conflitos criam ambiguidade sobre qual identificador está sendo referenciado.
  • Use um nome diferente para parâmetros de tipo interno que sombream os externos (CS0693, CS8387). Quando um membro genérico (como um método ou tipo aninhado) está dentro de uma classe ou método genérico, o parâmetro de tipo interno não é necessariamente o mesmo que o externo. Dar-lhes o mesmo nome cria confusão sobre qual parâmetro de tipo está sendo referenciado. Use um nome distinto para o parâmetro de tipo interno.
  • Verifique se todos os parâmetros de tipo em cláusulas de restrição são declarados na lista de parâmetros de tipo (CS0699). Uma where cláusula só pode referenciar parâmetros de tipo que aparecem na declaração genérica. Se o nome na cláusula where não corresponder a nenhum parâmetro de tipo declarado, verifique se há erros de digitação ou ortografia.
  • Use a sintaxe da declaração de registro correta (CS9012). Ao declarar um tipo de registro, você deve usar ou record classrecord struct (ou apenas record para um tipo de referência). A record palavra-chave por si só não pode aparecer em posições em que o compilador espera uma sintaxe de declaração diferente.

Para obter mais informações, consulte Parâmetros de tipo genérico e genéricos.

Declaração de restrição e ordenação

  • CS0401: A new() restrição deve ser a última restrição restritiva especificada.
  • CS0406: A restrição de tipo de classe 'constraint' deve vir antes de qualquer outra restrição.
  • CS0409: Uma cláusula de restrição já foi especificada para o parâmetro de tipo "parâmetro de tipo". Todas as restrições para um parâmetro de tipo devem ser especificadas em uma única cláusula where.
  • CS0449: As classrestrições , , structunmanagednotnulle default , não podem ser combinadas ou duplicadas, e devem ser especificadas primeiro na lista de restrições.
  • CS0450: Parâmetro de tipo: não é possível especificar simultaneamente uma classe de restrição e as restrições class ou struct.
  • CS0451: A new() restrição não pode ser usada com a restrição struct .
  • CS8375: A restrição 'new()' não pode ser usada com a restrição 'não gerenciada'.
  • CS8380: 'type': não é possível especificar uma classe de restrição e a restrição 'não gerenciada'.
  • CS9011: A palavra-chave delegate não pode ser usada como uma restrição. Você quis dizer System.Delegate?

As restrições nos parâmetros de tipo devem seguir uma ordem específica: restrições primárias (class, , struct, unmanagednotnullou default) vêm primeiro, depois uma restrição de tipo de classe, seguida por restrições de interface e, por fim, a restrição do new() construtor. Algumas restrições são mutuamente exclusivas e não podem ser combinadas. Todas as restrições para um único parâmetro de tipo devem aparecer em uma única where cláusula.

  • Coloque a new() restrição no final da lista de restrições (CS0401). A new() restrição deve aparecer após todas as outras restrições. Por exemplo, altere where T : new(), IDisposable para where T : IDisposable, new().
  • Coloque a restrição de tipo de classe antes das restrições de interface (CS0406). Quando você restringe um parâmetro de tipo a uma classe base específica junto com interfaces, a classe deve aparecer primeiro. Por exemplo, altere where T : IDisposable, MyBaseClass para where T : MyBaseClass, IDisposable.
  • Combine todas as restrições para um parâmetro de tipo em uma única where cláusula (CS0409). Você não pode usar várias where cláusulas para o mesmo parâmetro de tipo. Mescle-as em uma cláusula: altere where T : I where T : new() para where T : I, new(). Várias where cláusulas só são válidas quando são direcionadas a diferentes parâmetros de tipo.
  • Coloque as restrições primárias primeiro e não combine restrições mutuamente exclusivas (CS0449). Você pode especificar no máximo um de class, struct, unmanaged, notnullou default, e ele deve aparecer primeiro na lista de restrições. As restrições class e struct são mutuamente exclusivas, assim como class e unmanaged.
  • Não combine uma restrição de classe específica com class, structou unmanaged (CS0450, CS8380). Se um parâmetro de tipo estiver restrito a um tipo de classe específico, ele será implicitamente um tipo de referência, o que contradiz a restrição struct ou unmanaged. Remova a restrição de classe ou a restrição primária.
  • Não combine new() com struct ou unmanaged (CS0451, CS8375). Todos os tipos de valor têm implicitamente um construtor público sem parâmetros, portanto, a new() restrição é redundante quando combinada com struct. O mesmo se aplica a unmanaged, o que implica struct. Remova a new() restrição.
  • Substitua delegate por System.Delegate cláusulas de restrição (CS9011). A delegate palavra-chave é usada para declarar tipos delegados, não como uma restrição. Para restringir um parâmetro de tipo a tipos delegados, use System.Delegate como o tipo de restrição.

Para obter mais informações, consulte Restrições em parâmetros de tipo.

Tipos de restrição válidos

  • CS0405: restrição duplicada para o parâmetro de tipo.
  • CS0701: 'identifier' não é uma restrição válida. Um tipo usado como uma restrição deve ser uma interface, uma classe não lacrada ou um parâmetro de tipo.
  • CS0702: a restrição não pode ser uma classe especial.
  • CS0703: acessibilidade inconsistente: o tipo de restrição é menos acessível que a declaração.
  • CS0706: tipo de restrição inválido. Um tipo usado como uma restrição deve ser uma interface, uma classe não lacrada ou um parâmetro de tipo.
  • CS0717: classe estática: classes estáticas não podem ser usadas como restrições.
  • CS3024: O tipo de restrição 'type' não é compatível com CLS.

Uma restrição deve ser uma interface, uma classe não lacrada ou um parâmetro de tipo. Determinados tipos são inválidos como restrições devido ao seu significado especial no sistema de tipos .NET ou porque não podem ser herdados.

  • Remover restrições duplicadas (CS0405). Cada restrição só pode aparecer uma vez em uma cláusula de restrição. Se você tiver where T : I, I, remova a duplicata.
  • Use apenas tipos não lacrados como restrições (CS0701). Classes, structs e enums selados não podem ser herdados, portanto não têm utilidade como restrições. Use uma interface que os tipos desejados implementem ou use uma classe base não lacrada.
  • Não use classes especiais como restrições (CS0702). Os tipos Objecte ArrayValueType não podem ser usados como restrições. Cada tipo já deriva de Object, portanto, restringir a ele não fornece nenhum valor. Array e ValueType são tipos base abstratos que não podem ser herdados diretamente. Se você precisar de um comportamento semelhante à matriz, use IList<T> ou IEnumerable<T> em vez disso.
  • Verifique se os tipos de restrição são pelo menos tão acessíveis quanto o tipo genérico (CS0703). Um tipo genérico público não pode ter restrições usando tipos internos, pois o código externo não seria capaz de fornecer argumentos de tipo válidos. Torne o tipo de restrição público ou reduza a acessibilidade do tipo genérico.
  • Use apenas interfaces, classes não lacradas ou parâmetros de tipo como restrições (CS0706). Você não pode usar matrizes, classes lacradas, structs, enums ou outros tipos inválidos como restrições. Considere usar uma interface que os tipos desejados implementam.
  • Não use classes estáticas como restrições (CS0717). As classes estáticas não podem ser estendidas porque contêm apenas membros estáticos. Nenhum tipo pode derivar de uma classe estática, tornando-a inútil como uma restrição.
  • Use um tipo em conformidade com CLS para a restrição de tipo (CS3024). Quando um assembly é marcado com [assembly: CLSCompliant(true)], usar um tipo não compatível com CLS como restrição de tipo genérico pode tornar impossível que o código escrito em algumas linguagens use sua classe genérica.

Para obter mais informações, consulte Restrições em parâmetros de tipo.

Satisfação de restrições e conversões de processos

  • CS0311: O tipo não pode ser usado como parâmetro T de tipo no tipo genérico ou método. Não há nenhuma conversão de referência implícita de 'type1' para 'type2'.
  • CS0312: O tipo não pode ser usado como parâmetro de tipo no tipo ou método genérico. O tipo anulável não atende à restrição de 'constraint'.
  • CS0313: O tipo não pode ser usado como parâmetro de tipo no tipo ou método genérico. O tipo anulável não atende à restrição de 'constraint'. Tipos que permitem valor nulo não podem atender a nenhuma restrição de interface.
  • CS0314: O tipo não pode ser usado como parâmetro de tipo no tipo genérico ou no método. Não há conversão de boxing nem conversão de parâmetro de tipo de 'type' para 'constraint'.
  • CS0315: O tipo não pode ser usado como parâmetro de tipo T no tipo ou método genérico. Não há conversão de empacotamento de 'type' para 'constraint'.
  • CS0452: O tipo "nome do tipo" deve ser um tipo de referência para usá-lo como parâmetro 'nome do parâmetro' no tipo genérico ou método 'genérico'.
  • CS0453: O tipo 'nome do tipo' deve ser um tipo de valor não anulável para usá-lo como parâmetro 'nome do parâmetro' no tipo genérico ou método 'genérico'.
  • CS8377: O tipo 'type' deve ser um tipo de valor não anulável, bem como todos os campos em qualquer nível de aninhamento, para usá-lo como parâmetro 'parameter' no tipo genérico ou método 'generic'.

Esses erros ocorrem quando um argumento de tipo não atende às restrições declaradas em um parâmetro de tipo genérico. O argumento type deve ter as conversões corretas, relações de herança e propriedades estruturais para corresponder a todas as restrições.

  • Altere o argumento de tipo para um que tenha uma conversão de referência implícita para o tipo de restrição (CS0311). Quando um parâmetro de tipo tem uma restrição como where T : BaseType, qualquer argumento de tipo deve ser conversível BaseType por meio de uma conversão de referência implícita ou conversão de identidade. Conversões numéricas implícitas (como de short para int) não satisfazem as restrições de parâmetros de tipo genérico.
  • Use tipos de valor não anuláveis ou altere o tipo de restrição (CS0312, CS0313). Tipos de valor anuláveis (como int?) são distintos de seus tipos de valor subjacentes e não atendem às mesmas restrições. Tipos de valor anuláveis não podem satisfazer restrições de interface porque o wrapper anulável em si não implementa a interface. Use a forma não anulável do tipo de valor como o argumento de tipo.
  • Repita as restrições de parâmetro de tipo da classe base em qualquer declaração de classe derivada (CS0314). Quando uma classe genérica derivada herda de uma classe genérica base restrita, a classe derivada deve declarar as mesmas restrições em seus parâmetros de tipo correspondentes.
  • Verifique se os argumentos de tipo atendem ao tipo de referência ou às restrições de classe (CS0315). Quando um parâmetro de tipo é restringido a um tipo de classe, você não pode usar um tipo de valor (struct) como argumento de tipo, porque não há conversão de empacotamento que satisfaça a relação de restrição. Use um tipo de referência que herda ou implementa a restrição.
  • Use um tipo de referência como o argumento de tipo quando a class restrição for especificada (CS0452). Tipos de valor como struct ou int não podem satisfazer uma class restrição. Altere o argumento de tipo para um tipo de referência ou remova a class restrição se o tipo genérico puder trabalhar com tipos de valor.
  • Use um tipo de valor não anulável como o argumento de tipo quando a struct restrição for especificada (CS0453). Tipos de referência, tipos de valor anuláveis (int?) e outros tipos que não são de valor não podem atender a uma struct restrição. Use um tipo de valor concreto, não anulável, como int, doubleou um definido pelo structusuário.
  • Use um tipo cujos campos são todos tipos não gerenciados quando a unmanaged restrição for especificada (CS8377). A restrição unmanaged requer um tipo de valor não anulável no qual cada campo, em cada nível de aninhamento, também deve ser um tipo não gerenciado. Tipos que contêm campos de tipo de referência ou parâmetros de tipo genérico que não se sabe se são não gerenciados não satisfazem essa restrição.

Para obter mais informações, consulte Restrições em parâmetros de tipo.

Conflitos de restrição e dependências circulares

  • CS0454: dependência de restrição circular envolvendo o Parâmetro de Tipo 1 e o Parâmetro de Tipo 2.
  • CS0455: o parâmetro Type herda restrições conflitantes 'constraint1' e 'constraint2'.
  • CS0456: o parâmetro de tipo 'type parameter 1' tem a restrição 'struct' para que 'type parameter 1' não possa ser usado como uma restrição para 'type parameter 2'.
  • CS8379: o parâmetro de tipo 'type parameter 1' tem a restrição 'unmanaged' para que 'type parameter 1' não possa ser usado como uma restrição para 'type parameter 2'.

As restrições não podem criar dependências circulares e os parâmetros de tipo não podem herdar restrições conflitantes que são impossíveis de satisfazer simultaneamente. Restrições de tipo de valor (struct e unmanaged) são implicitamente lacradas, portanto, elas não podem ser usadas como restrições em outros parâmetros de tipo.

  • Remova as dependências de restrição circular (CS0454). Um parâmetro de tipo não pode depender direta ou indiretamente de si mesmo por meio de suas restrições. Por exemplo, where T : U where U : T cria uma dependência circular. Quebre o ciclo removendo uma das restrições.
  • Remova restrições herdadas conflitantes (CS0455). Um parâmetro de tipo não pode ser restrito a várias classes não relacionadas, pois o C# não dá suporte a herança de várias classes. Da mesma forma, ele não pode ser restrito a ambos struct e a um tipo de classe. Reestruturar sua hierarquia de tipos ou remover uma das restrições conflitantes.
  • Não use um parâmetro de tipo com restrição struct ou um parâmetro de tipo com restrição unmanaged como restrição para outro parâmetro de tipo (CS0456, CS8379). As restrições de tipo de valor são implicitamente seladas, portanto, nenhum outro tipo pode derivar delas. Para resolver esse erro, coloque o tipo de valor ou a restrição não gerenciada diretamente no segundo parâmetro de tipo em vez de restringi-lo indiretamente por meio do primeiro parâmetro de tipo.

Para obter mais informações, consulte Restrições em parâmetros de tipo.

Regras de restrição de substituição e implementação

  • CS8665: o método 'method' especifica uma restrição 'class' para o parâmetro de tipo 'type parameter', mas o parâmetro de tipo correspondente 'type parameter' do método 'method' substituído ou explicitamente implementado não é um tipo de referência.
  • CS8666: O método 'method' especifica uma restrição 'struct' para o parâmetro de tipo 'type parameter', mas o parâmetro de tipo correspondente 'type parameter' do método 'method' substituído ou explicitamente implementado não é um tipo de valor não anulável.
  • CS8822: o método 'method' especifica uma restrição 'default' para o parâmetro de tipo 'type parameter', mas o parâmetro de tipo correspondente 'type parameter' do método 'method' substituído ou explicitamente implementado é restrito a um tipo de referência ou um tipo de valor.
  • CS8823: A restrição 'padrão' é válida somente em métodos de substituição e implementação de interface explícita.

Quando você substitui um método virtual ou implementa explicitamente um método de interface, as restrições nos parâmetros de tipo do método de substituição devem ser compatíveis com as restrições do método base. A restrição default é um modificador especial usado apenas em cenários de sobrescrita e implementação explícita de interface para indicar que um parâmetro de tipo não tem restrição class nem struct.

  • Verifique se as restrições do método de substituição correspondem às restrições do método base (CS8665, CS8666). Uma substituição não poderá adicionar uma class restrição se o parâmetro de tipo correspondente do método base não for restrito a um tipo de referência. Da mesma forma, ele não poderá adicionar uma struct restrição se o parâmetro de tipo do método base não estiver restrito a um tipo de valor. A substituição deve ser compatível com a declaração base.
  • Use a restrição default somente quando o parâmetro de tipo do método base estiver sem restrições (CS8822). A default restrição indica que o parâmetro de tipo não tem nenhuma class restrição ou struct restrição. Não é possível aplicar default se o parâmetro de tipo correspondente do método substituído já tiver uma restrição class ou struct.
  • Use a restrição default somente em métodos de substituição ou de implementação explícita de interface (CS8823). A default restrição não é válida em declarações de método regulares. Ele existe especificamente para desambiguar ao substituir um método em que a base tinha um parâmetro de tipo não treinado e você precisa indicar que a substituição também o deixa sem restrições.

Para obter mais informações, consulte Restrições nos parâmetros de tipo e a default restrição.

Restrições do construtor

  • CS0304: Não é possível criar uma instância do tipo de variável porque ela não tem a new() restrição.
  • CS0310: O tipo deve ser um tipo não abstrato com um construtor público sem parâmetros para usá-lo como parâmetro no tipo ou método genérico.
  • CS0417: Identificador: não é possível fornecer argumentos ao criar uma instância de um tipo de variável.

Esses erros estão relacionados à restrição new() e à instanciação de parâmetros de tipo com o new operador.

  • Adicione a new() restrição aos parâmetros de tipo que você precisa para instanciar (CS0304). Quando você usa new T() dentro de um tipo ou método genérico, o compilador deve garantir que qualquer argumento de tipo tenha um construtor sem parâmetros. A new() restrição fornece essa garantia.
  • Verifique se os argumentos de tipo têm construtores públicos sem parâmetros (CS0310). Quando um parâmetro de tipo tem a new() restrição, qualquer tipo concreto usado como um argumento de tipo deve ser não abstrato e deve fornecer um construtor público sem parâmetros. Tipos com apenas construtores privados, protegidos ou parametrizados não podem satisfazer a new() restrição.
  • Remova argumentos de construtor ao instanciar parâmetros de tipo (CS0417). A new() restrição garante apenas um construtor sem parâmetros. Você não pode passar argumentos para new T(arguments). Se você precisar construir instâncias com argumentos específicos, considere usar um padrão de fábrica ou uma restrição de interface que defina o comportamento de construção.

Para obter mais informações, consulte Restrições nos parâmetros de tipo e a new() restrição.

Contagem e utilização de argumentos de tipo

  • CS0224: um método com vararg não pode ser genérico, estar em um tipo genérico ou ter um parâmetro params.
  • CS0305: o uso do tipo genérico requer argumentos de tipo N.
  • CS0306: O tipo pode não ser usado como um argumento de tipo.
  • CS0307: o 'identificador' não pode ser usado com argumentos de tipo.
  • CS0308: O tipo ou método não genérico não pode ser usado com argumentos de tipo.
  • CS7002: uso inesperado de um nome genérico.
  • CS8389: omitir o argumento de tipo não é permitido no contexto atual.

Esses erros estão relacionados ao fornecimento do número e do tipo corretos de argumentos para tipos e métodos genéricos.

  • Remova parâmetros de tipo genérico ou que contenham declarações de tipo genérico de métodos que usam __arglist (CS0224). A __arglist palavra-chave é incompatível com genéricos porque os mecanismos de runtime para lidar com listas de argumentos variáveis entram em conflito com a substituição de tipo necessária para parâmetros de tipo genérico.
  • Forneça o número exato de argumentos de tipo especificados na declaração genérica (CS0305). Cada parâmetro de tipo genérico na definição deve ter um argumento de tipo correspondente quando o tipo genérico é instanciado.
  • Use apenas tipos válidos como argumentos de tipo (CS0306). Tipos de ponteiro (como int* ou char*) não podem ser usados como argumentos de tipo porque tipos genéricos exigem tipos gerenciados que o coletor de lixo pode rastrear.
  • Remova a sintaxe de argumento de tipo de constructos não genéricos (CS0307, CS0308). Argumentos de tipo entre colchetes angulares só podem ser aplicados a tipos genéricos e métodos que declaram parâmetros de tipo. Verifique se você importou o namespace que contém a versão genérica do tipo.
  • Remova parâmetros de tipo de declarações que não dão suporte a genéricos (CS7002). Alguns constructos, como enumerações, não podem ser genéricos. Se você precisar de um contêiner genérico para valores de enum, considere usar uma classe ou struct genérica.
  • Forneça todos os argumentos de tipo necessários explicitamente (CS8389). Em alguns contextos, como usar o typeof operador ou criar delegados, você deve fornecer todos os argumentos de tipo e não pode omitê-los. Por exemplo, use typeof(List<int>) em vez de tentar omitir o argumento de tipo.

Para obter mais informações, consulte Parâmetros de tipo genérico e genéricos.

Inferência de argumento de tipo

  • CS0411: os argumentos de tipo para o método 'method' não podem ser inferidos do uso. Tente especificar explicitamente os argumentos de tipo.

Esse erro ocorre quando você chama um método genérico sem fornecer explicitamente os argumentos de tipo e o compilador não pode inferir quais argumentos de tipo você pretende. O compilador infere os argumentos de tipo com base nos tipos dos argumentos do método que você passa no local da chamada.

  • Especifique os argumentos de tipo explicitamente em colchetes angulares (CS0411). Se o compilador não puder determinar os argumentos de tipo dos argumentos do método, forneça-os diretamente. Por exemplo, altere G() para G<int>(). Esse erro geralmente ocorre quando um método genérico não tem parâmetros dos quais inferir o tipo ou quando um null argumento é passado e o compilador não pode determinar o tipo pretendido.

Para obter mais informações, consulte Métodos Genéricos.

Variação de parâmetro de tipo

  • CS1960: modificador de variação inválido. Somente parâmetros de interface e de tipo delegado podem ser especificados como variante.
  • CS1961: Variação inválida: o parâmetro de tipo deve ser covariantemente válido em 'type'. 'type parameter' é contravariante.
  • CS8427: Enums, classes e estruturas não podem ser declarados em uma interface que tenha um parâmetro de tipo 'in' ou 'out'.

Modificadores de variação (in para contravariância, out para covariância) controlam como você pode usar parâmetros de tipo em declarações de interface e delegado. Somente interfaces e delegados oferecem suporte à variância. Um parâmetro de tipo covariante (out) só pode aparecer em posições de saída (tipos de retorno), enquanto um parâmetro de tipo contravariante (in) só pode aparecer em posições de entrada (tipos de parâmetro).

  • Use modificadores de variação somente em parâmetros de tipo de interface e delegado (CS1960). Classes, structs e outras declarações de tipo não dão suporte a modificadores de variação. Somente interface e delegate declarações podem usar in ou out em seus parâmetros de tipo.
  • Use out (covariante) para parâmetros de tipo que aparecem apenas em tipos de retorno, e in (contravariante) para parâmetros de tipo que aparecem apenas em tipos de parâmetro (CS1961). Se o parâmetro de tipo precisar aparecer nas posições de entrada e saída, remova o modificador de variação.
  • Não declare enums, classes ou estruturas dentro de uma interface variante (CS8427). Declarações de tipo aninhadas dentro de uma interface que possui parâmetros de tipo in ou out não são permitidas porque podem violar as regras de segurança de variância. Mova o tipo aninhado para fora da declaração de interface.

Para obter mais informações, consulte Covariância e Contravariância em Genéricos.

Restrições de uso de tipo genérico

  • CS0403: não é possível converter nulo em parâmetro de tipo porque ele pode ser um tipo de valor não anulável. Considere usar default(T) em vez disso.
  • CS0413: O parâmetro de tipo não pode ser usado com o as operador porque ele não tem uma restrição de tipo de classe nem uma restrição class .
  • CS0695: 'type' não pode implementar ambas 'interface1' e 'interface2' porque elas podem se unificar devido a algumas substituições de parâmetros de tipo.
  • CS0698: um tipo genérico não pode derivar do tipo porque é uma classe de atributo.
  • CS0704: Não é possível fazer pesquisa de membro não virtual em 'type' porque é um parâmetro de tipo.
  • CS0718: 'type': tipos estáticos não podem ser usados como argumentos de tipo.
  • CS1720: A expressão sempre causará um System.NullReferenceException porque o valor padrão de "tipo genérico" é nulo.
  • CS1763: 'parameter' é do tipo 'type'. Um valor de parâmetro padrão de um tipo de referência diferente de cadeia de caracteres só pode ser inicializado com nulo.
  • CS8322: não é possível passar argumento com tipo dinâmico para função local genérica com argumentos de tipo inferidos.
  • CS9338: Acessibilidade inconsistente: o tipo é menos acessível que a classe.

Esses erros estão relacionados a restrições sobre como tipos genéricos e parâmetros de tipo podem ser usados em expressões, herança e acesso de membro.

  • Substitua null as atribuições por default(T) ou adicione uma class restrição (CS0403). Quando você atribui null a um parâmetro de tipo sem restrições, o compilador não pode garantir que o argumento de tipo seja um tipo de referência. Use default(T), que fornece o valor padrão apropriado para qualquer tipo ou adicione uma class restrição se você precisar especificamente de semântica de tipo de referência.
  • Adicione uma restrição de tipo específica ou class ao usar o operador as (CS0413). O as operador retornará null se a conversão falhar, mas os tipos de valor não poderão ser null. Adicione uma class restrição para garantir que o parâmetro de tipo seja sempre um tipo de referência.
  • Evite implementar a mesma interface genérica várias vezes com parâmetros de tipo que possam unificar (CS0695). Quando uma classe implementa uma interface genérica várias vezes com parâmetros de tipo diferentes (como class G<T1, T2> : I<T1>, I<T2>), criar uma instância com o mesmo tipo para ambos os parâmetros criaria um conflito. Implemente a interface apenas uma vez ou reestruture para impedir a unificação.
  • Remova parâmetros de tipo genérico das classes de atributo (CS0698). Esse erro não é mais produzido nas versões atuais do C#, pois agora há suporte para atributos genéricos.
  • Use o tipo de restrição concreta em vez do parâmetro de tipo para acesso de membro aninhado (CS0704). Você não pode acessar tipos aninhados ou membros não virtuais por meio de um parâmetro de tipo. Em vez de usar diretamente o tipo de restrição conhecido, como BaseClass.InnerType, use T.InnerType.
  • Não use tipos estáticos como argumentos de tipo (CS0718). Tipos estáticos não podem ser instanciados e não podem ser usados como argumentos genéricos. Remova o tipo estático do argumento genérico.
  • Evite chamar membros de instância em default(T) quando T estiver restrito a um tipo de referência (CS1720). Quando T tem uma restrição class, default(T) é null, portanto chamar membros de instância nele sempre gera uma NullReferenceException. Adicione uma verificação nula antes de chamar membros ou reestruture o código para evitar o uso default(T) diretamente.
  • Use null como o valor de parâmetro padrão para parâmetros opcionais cujo tipo é um tipo de referência (CS1763). Se um método genérico tiver um parâmetro de tipo T e T for um tipo de referência, substitua default(U)null porque os padrões de parâmetro opcional devem ser constantes de tempo de compilação e default(T) não corrigirão esse requisito.
  • Especifique explicitamente argumentos de tipo ao passar valores dinâmicos para funções locais genéricas (CS8322). Quando você passa um dynamic argumento para uma função local genérica, o compilador não pode inferir argumentos de tipo. Especifique explicitamente o argumento de tipo ou converta o valor dinâmico.
  • Verifique se os argumentos de tipo usados em assinaturas públicas ou protegidas são pelo menos tão acessíveis quanto o membro (CS9338). Um membro genérico público deve usar argumentos de tipo que sejam publicamente acessíveis. Torne o argumento de tipo público, ou reduza a acessibilidade do membro.

Para obter mais informações, consulte Restrições em parâmetros de tipo e expressões de valor padrão.

Restrições UnmanagedCallersOnly

  • CS8893: 'type' não é um tipo de convenção de chamada válido para 'UnmanagedCallersOnly'.
  • CS8894: não é possível usar 'type' como um parâmetro ou tipo de retorno em um método atribuído com 'UnmanagedCallersOnly'.
  • CS8895: os métodos atribuídos com 'UnmanagedCallersOnly' não podem ter parâmetros de tipo genérico e não podem ser declarados em um tipo genérico.
  • CS8896: 'UnmanagedCallersOnly' só pode ser aplicado a métodos estáticos não abstratos, não virtuais ou funções locais estáticas.

O UnmanagedCallersOnlyAttribute atributo marca os métodos que o código não gerenciado pode chamar. Esses métodos têm requisitos estritos porque o runtime deve lidar com a transição entre convenções de chamada gerenciadas e não gerenciadas.

  • Use apenas tipos de convenção de chamada válidos no UnmanagedCallersOnly atributo (CS8893). A CallConvs propriedade do atributo aceita apenas tipos de convenção de chamada reconhecidos do System.Runtime.CompilerServices namespace.
  • Use apenas tipos blittable como tipos de parâmetros e de retorno (CS8894). Métodos marcados com UnmanagedCallersOnly não podem usar tipos gerenciados (como string ou object) como parâmetro ou tipo de retorno, porque chamadores não gerenciados não podem gerenciar referências coletadas pelo coletor de lixo.
  • Remova os parâmetros de tipo genérico dos UnmanagedCallersOnly métodos e não os declare em tipos genéricos (CS8895). Convenções de chamada não gerenciadas não dão suporte a genéricos porque o runtime não pode determinar a convenção de chamada correta para substituições de tipo genérico.
  • Aplique-se UnmanagedCallersOnly somente a métodos estáticos, não abstratos, não virtuais comuns ou a funções locais estáticas (CS8896). Métodos de instância, métodos abstratos e métodos virtuais não podem ser marcados UnmanagedCallersOnly porque os chamadores não gerenciados não podem executar os mecanismos de expedição que esses métodos exigem.

Para obter mais informações, consulte UnmanagedCallersOnlyAttribute.